Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ready for review. #30

Merged
merged 4 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
75 changes: 75 additions & 0 deletions src/guides/components/findings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 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.
dedupeKey: `${request.getHost()}-${request.getPath()}`, // Prevents multiple alerts for request with matching characteristics (optional).
request, // The associated request.
});
```

::: tip
The `dedupeKey` can be any value, including [request](https://developer.caido.io/reference/sdks/backend/#request) or [response](https://developer.caido.io/reference/sdks/backend/#response-3) object properties (_besides the body element_). If the value is detected a second time, the Finding will be considered a duplicate and an alert will not be generated.

``` ts
// Dedupe based on a string.
dedupeKey: "Hello world!"
// Dedupe based on request path and method.
dedupeKey: `${request.getPath()}-${request.getMethod()}`
// Dedupe based on request path, response code and response header.
dedupeKey: `${request.getPath()}-${response.getCode()}-${response.getHeader("Content-Length")}`
```

:::

## 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}`);
}
});
}
```

## 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
Loading