Serpico Documentation
repository·master·Indexed 22 days ago
https://github.com/buffalowill/serpicoA penetration testing report generation and collaboration tool that automates the creation of information security reports using Microsoft Word templates and a shared findings database. It features a custom Meta-Language for mapping UI data to .docx files, a Template Database for reusing findings, and an attachment system for team collaboration. Installation is supported via Docker and Docker Compose.
What's inside Serpico
- CodeMirror is a JavaScript-based text editor designed for the browser, specifically optimized for code editing. It features over 100 language modes providing syntax highlighting and a variety of addons for advanced editing capabilities. Developers can customize the editor using a rich programming API and a CSS-based theming system.
How Serpico report generation works
masterSerpico is a penetration testing report generation tool that uses a template-based workflow:
- Findings: Users select "findings" from a central Template Database and add them to a report.
- Templates: A Report Template (in
.docxformat) defines the design of the final document. A default template is included, but users can upload their own via the UI. - Meta-Language: Templates use a custom Microsoft Word Meta-Language to stub data (such as findings or customer names) from the Serpico UI into the Word document.
- Generation: Once sufficient findings are added, clicking 'Generate Report' produces the final
.docxfile.
Use the Template Database for findings
masterTo avoid writing findings from scratch, Serpico provides a Template Database.
- Reuse: Authors can pull existing findings from the database and add them to a current report.
- Contribute: Users can 'Upload' new findings they have created into the Template Database to make them available to the rest of the team.
Collaborate using Attachments
masterSerpico includes an 'Add Attachment' feature designed for team collaboration during penetration tests. You can use this to:
- Store files like screenshots or
nmapscans. - Share files with teammates via the UI without using email or physical media.
- Centralize all assets generated or traded during an assessment in one location.
- Store files like screenshots or
Build and run CodeMirror locally
masterTo build the CodeMirror project from source, ensure you have Node.js (version 6 or higher) installed. You can then install dependencies and run the project using the following steps:
- Install dependencies:
npm install - Run the project: Open
index.htmldirectly in your browser (a webserver is not required). - Run tests: Use
npm testto execute the test suite.
npm install npm test- Install dependencies:
Create Report Templates with Microsoft Word Meta-Language
masterSerpico uses a custom Meta-Language within Microsoft Word to map UI data to the report.
Best Practices:
- The Meta-Language has a learning curve; it is highly recommended to avoid starting from scratch.
- Instead, open existing template files such as
Serpico - Report.docxorSerpico - No DREAD.docxand edit them to suit your needs. - Once you have modified a template, upload it back through the Serpico UI to use it for future reports.
Install Serpico using Docker
masterThe preferred method of installation is using Docker. This method sets up the necessary volumes for the database, temporary files, and attachments to ensure data persistence on your host machine.
- Create and enter a working directory:
mkdir SERPICO cd SERPICO - Run the Serpico Docker container, mapping port
8443and mounting local directories fordb,tmp, andattachments:docker run --name serpico -p 8443:8443 \ -v"$(pwd)/db":/Serpico/db -v"$(pwd)/tmp":/Serpico/tmp \ -v"$(pwd)/attachments":/Serpico/attachments \ -it serpico/serpico - Access the UI at
https://127.0.0.1:8443.
mkdir SERPICO cd SERPICO docker run --name serpico -p 8443:8443 \ -v"$(pwd)/db":/Serpico/db -v"$(pwd)/tmp":/Serpico/tmp \ -v"$(pwd)/attachments":/Serpico/attachments \ -it serpico/serpico- Create and enter a working directory:
Understand the Context and State in mode parsing
masterMode parsing relies on two main concepts:
- State: A user-defined object that tracks the current parsing status (e.g., whether we are inside a string or a comment). Use
copyState(mode, state)to create a clone of the state to avoid side effects. - Context: An object used during the highlighting process that tracks the current line, the document, and the
state. It allows forlookAheadoperations to see subsequent lines.
When a mode needs to switch to a different mode (e.g., entering a nested block), it uses
innerMode(mode, state)to return the new mode and its corresponding state.- State: A user-defined object that tracks the current parsing status (e.g., whether we are inside a string or a comment). Use
Understand the CodeMirror Display Update lifecycle
masterThe
DisplayUpdateobject manages the process of synchronizing the editor's internal state with the DOM. When the document changes, CodeMirror calculates aDisplayUpdateto determine what needs to be redrawn.The Update Process
- Viewport Calculation: The editor determines which lines are visible based on the current scroll position and
viewportMargin. - View Adjustment:
adjustViewensures the internaldisplay.viewcovers the required range, adding or clipping elements as needed. - DOM Patching:
patchDisplaysynchronizes thelineDivDOM structure with the currentdisplay.view, adding new line nodes or updating existing ones. - Post-Update: After the DOM is patched, the editor updates scrollbars, selection, and document height to match the new layout.
- Viewport Calculation: The editor determines which lines are visible based on the current scroll position and
How CodeMirror handles line heights and widgets
masterCodeMirror dynamically manages line heights to accommodate text and embedded widgets.
- Estimation: When lines are not yet visible or measured,
estimateHeight(cm)provides a first approximation. This calculation accounts forcm.options.lineWrappingand any widgets attached to the line. - Updating:
updateHeightsInViewport(cm)reads actual DOM heights of rendered lines and updates the document's stored line heights. This ensures that scrolling and cursor positioning remain accurate. - Widgets:
updateWidgetHeight(line)ensures that the height of widgets associated with a line is synchronized with their actual DOM height.
- Estimation: When lines are not yet visible or measured,
Manage editor focus and blinking with `onFocus` and `onBlur`
masterCodeMirror manages focus state and cursor blinking through internal lifecycle methods.
- Focusing:
onFocus(cm, e)setscm.state.focused = true, adds theCodeMirror-focusedclass to the wrapper, and restarts the cursor blink cycle viarestartBlink(cm). Ifcm.options.readOnlyis set to'nocursor', focus behavior is restricted. - Blurring:
onBlur(cm, e)setscm.state.focused = false, removes theCodeMirror-focusedclass, and stops the cursor blink interval. - Blinking: The cursor blink rate is controlled by
cm.options.cursorBlinkRate. A value> 0enables blinking, while< 0hides the cursor.
- Focusing:
Manage editor state changes with operations
masterCodeMirror uses an 'operation' pattern to batch multiple changes to the editor state. This prevents expensive and error-prone intermediate updates to the cursor and display. When you wrap changes in an operation, the display updates are deferred and executed all at once when the operation finishes.
To run a function within an operation, use
runInOp(cm, f). If an operation is already in progress, it executes the function immediately. Otherwise, it starts a new operation, runs the function, and ensures the operation is closed.To create a function that always runs within an operation (even if one is already active), use
operation(cm, f).// Run a function within a new or existing operation runInOp(cm, function() { // Perform multiple editor changes here // The display will only update once at the end }); // Create a reusable function that automatically handles operations const myWrappedFunction = operation(cm, function(arg1) { // Logic here });