Skip to content

Commit

Permalink
Ready for review.
Browse files Browse the repository at this point in the history
  • Loading branch information
ninjeeter committed Dec 17, 2024
1 parent 8ac07db commit bc9fe25
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
4 changes: 4 additions & 0 deletions .vitepress/sidebars/guides.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ export const guidesSidebar: DefaultTheme.SidebarItem[] = [
text: "Storing Data in SQLite",
link: "/guides/components/sqlite",
},
{
text: "Using Findings",
link: "/guides/components/findings",
},
{
text: "Using Invalid UTF-8",
link: "/guides/components/utf",
Expand Down
Binary file added src/_images/findings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions src/guides/components/findings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Using Findings

Any requests or responses can be parsed for notable characteristics based on conditional statements using [Findings](https://docs.caido.io/guides/findings.html). As Caido proxies traffic, if it detects what you are looking for, an alert will be generated to draw your attention.

## Creating Findings

To create a Finding, use `sdk.findings.create()`. The `title`, `reporter` and `request` properties are required:

``` ts
await sdk.findings.create({
title: "Title", // Label your Finding.
description: "Description", // Add a description (optional).
reporter: "Reporter", // Specify which plugin discovered the Finding.
dedupe: `${request.getHost()}-${request.getPath()}`, // Prevents multiple alerts for request with matching characteristics (optional).
request, // The associated request.
});
```

## Conditional Findings

You can then set conditions that must be met such as only creating a Finding if the request recieved a 200 response:

``` ts
import type { DefineAPI, SDK } from "caido:plugin";
import type { Request, Response } from "caido:utils";

export type API = DefineAPI<{
// No API methods needed for this passive functionality.
}>;

export function init(sdk: SDK<API>) {
// Listen for intercepted responses.
sdk.events.onInterceptResponse(
async (
sdk: SDK<API>,
request: Request,
response: Response
) => {
try {
// Only create Findings for 200 responses.
if (response.getCode() === 200) {
await sdk.findings.create({
title: `Success Response ${response.getCode()}`,
description: `Request ID: ${request.getId()}\nResponse Code: ${response.getCode()}`,
reporter: "Response Logger Plugin",
request: request,
dedupeKey: `${request.getPath()}-${response.getCode()}`
});

sdk.console.log(`Created finding for successful request ${request.getId()}`);
}
} catch (err) {
sdk.console.error(`Error creating finding: ${err}`);
}
});
}
```

::: tip
View all of the properties that can be accessed for [request](https://developer.caido.io/reference/sdks/backend/#request) and [response](https://developer.caido.io/reference/sdks/backend/#response-3) objects.
:::

## The Result

<img alt="Finding alert." src="/_images/findings.png" centered />
21 changes: 18 additions & 3 deletions src/guides/components/sqlite.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ For storing data generated by your plugin, Caido utilizes SQLite databases.

SQLite is a lightweight database engine made available via a small library. It requires no setup, administration or separate server. Instead, all data is stored in a single file.

## Getting a Database Path
## Getting a Database

The `sdk.meta.db()` utility provides a SQLite database specific to your plugin. You can view the location of the generated file using `sdk.meta.path()`:

Expand All @@ -15,6 +15,21 @@ const dataPath = sdk.meta.path();
sdk.console.log(`Database will be stored in: ${dataPath}`);
```

::: tip
To create a database at different location, use `open`:

``` ts
import { open } from 'sqlite'

async function newDatabase() {
const db = await open({ filename: "path/to/database.sqlite" });
await db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT);");
await db.exec("INSERT INTO test (name) VALUES ('foo');");
}
```

:::

## Creating Tables

You can run direct SQL statements by supplying them as an arguement to the `.exec()` method:
Expand Down Expand Up @@ -43,14 +58,14 @@ const insertStatement = await db.prepare("INSERT INTO test (name) VALUES (?)");
const result = await insertStatement.run("Ninjeeter");
```

## Retrieving Data

Using `.lastInsertRowid` will return the ID of the last inserted row:

``` ts
console.log(`Inserted row with ID: ${result.lastInsertRowid}`);
```

## Retrieving Data

To select all the columns in a table and return every row, use the wildcard character `*` and the `.all()` method:

``` ts
Expand Down

0 comments on commit bc9fe25

Please sign in to comment.