@ts-graphviz/adapter 3.0.3 → 3.0.4-next-2175a0b15ee57f675a1fda902b74d8359a5c05cb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +115 -0
- package/lib/types.d.ts +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @ts-graphviz/adapter
|
|
2
2
|
|
|
3
|
+
## 3.0.4-next-2175a0b15ee57f675a1fda902b74d8359a5c05cb
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1528](https://github.com/ts-graphviz/ts-graphviz/pull/1528) [`6966a66`](https://github.com/ts-graphviz/ts-graphviz/commit/6966a6699e87e2c74e7348aa6fdc2c50ae11b308) Thanks [@kamiazya](https://github.com/kamiazya)! - Add comprehensive security documentation for safe usage of adapter options
|
|
8
|
+
|
|
9
|
+
This patch adds security considerations and best practices documentation to clarify the safe usage of `dotCommand`, `library`, and user-provided DOT files.
|
|
10
|
+
|
|
11
|
+
**Changes:**
|
|
12
|
+
|
|
13
|
+
- Added security considerations section to README explaining spawn/Deno.Command behavior
|
|
14
|
+
- Added JSDoc security notes to `dotCommand` and `library` type definitions
|
|
15
|
+
- Included validation example showing how to sanitize user-uploaded DOT files using @ts-graphviz/ast
|
|
16
|
+
- Documented potentially dangerous attributes that can access file system resources
|
|
17
|
+
|
|
18
|
+
**Documentation Clarifications:**
|
|
19
|
+
|
|
20
|
+
- Explains that spawn/Deno.Command do not invoke shell interpreters, preventing shell injection
|
|
21
|
+
- Clarifies that configuration options should be controlled by developers, not end-users
|
|
22
|
+
- Provides working TypeScript example for validating and sanitizing untrusted DOT content
|
|
23
|
+
- Lists file-access attributes (image, shapefile, fontpath, etc.) that require validation
|
|
24
|
+
|
|
25
|
+
This documentation addresses security concerns while maintaining that the library itself has no vulnerabilities when used as designed.
|
|
26
|
+
|
|
3
27
|
## 3.0.3
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -93,6 +93,121 @@ await toFile(dot, './result.svg', { format: 'svg' });
|
|
|
93
93
|
|
|
94
94
|
Both functions accept configuration options to customize the rendering process.
|
|
95
95
|
|
|
96
|
+
## Configuration Options
|
|
97
|
+
|
|
98
|
+
### Security Considerations
|
|
99
|
+
|
|
100
|
+
The `dotCommand` and `library` options are intended to be configured by application developers, not derived from end-user input:
|
|
101
|
+
|
|
102
|
+
- **`dotCommand`**: Specifies the path to the Graphviz executable. This should be a trusted, hardcoded path in your application configuration.
|
|
103
|
+
- **`library`**: Specifies external libraries to load. These should be trusted library names defined in your application code.
|
|
104
|
+
|
|
105
|
+
**Important**: This library executes external commands using `spawn` (Node.js) or `Deno.Command` (Deno), which do not invoke a shell interpreter. This prevents shell injection attacks through metacharacters (`;`, `` ` ``, `|`, `$`, etc.). However, these options should not be exposed to end-user input.
|
|
106
|
+
|
|
107
|
+
#### Processing User-Provided DOT Files
|
|
108
|
+
|
|
109
|
+
When rendering DOT files uploaded by users or generated from user input, implement validation before passing them to this library:
|
|
110
|
+
|
|
111
|
+
**Validation Steps**:
|
|
112
|
+
1. **Syntax validation**: Verify the DOT file is well-formed and parseable
|
|
113
|
+
2. **Attribute filtering**: Check for potentially dangerous attributes that reference file system resources:
|
|
114
|
+
- `image`, `shapefile` - Can reference arbitrary image files
|
|
115
|
+
- `fontpath`, `fontname` - Can reference font files
|
|
116
|
+
- `imagepath` - Defines search path for images
|
|
117
|
+
3. **Content sanitization**: Consider using a DOT parser to rebuild the graph with only allowed attributes
|
|
118
|
+
4. **Sandboxing**: Run Graphviz in a sandboxed environment with restricted file system access when processing untrusted input
|
|
119
|
+
|
|
120
|
+
**Example Risk Scenario**:
|
|
121
|
+
|
|
122
|
+
⚠️ **Warning**: The following is an example of **unsafe** DOT content that should be rejected by validation:
|
|
123
|
+
|
|
124
|
+
```dot
|
|
125
|
+
digraph G {
|
|
126
|
+
node [image="/etc/passwd"]; // ⚠️ DANGEROUS: Attempts to access sensitive file
|
|
127
|
+
node1;
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
While Graphviz will handle file access errors gracefully, processing untrusted DOT files without validation may expose information about your file system or cause unexpected behavior. **Always validate and sanitize user-provided DOT files before processing.**
|
|
132
|
+
|
|
133
|
+
**Example: Validating and Sanitizing User-Provided DOT Files**
|
|
134
|
+
|
|
135
|
+
Here's an example of how to use the `@ts-graphviz/ast` package to parse, validate, and sanitize DOT files:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { parse, stringify } from '@ts-graphviz/ast';
|
|
139
|
+
|
|
140
|
+
// Potentially dangerous attributes that can access file system
|
|
141
|
+
const DANGEROUS_ATTRIBUTES = new Set([
|
|
142
|
+
'image',
|
|
143
|
+
'shapefile',
|
|
144
|
+
'fontpath',
|
|
145
|
+
'fontname',
|
|
146
|
+
'imagepath',
|
|
147
|
+
]);
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Validates and sanitizes a DOT file by removing dangerous attributes
|
|
151
|
+
*/
|
|
152
|
+
function validateAndSanitizeDOT(dotString: string): string {
|
|
153
|
+
try {
|
|
154
|
+
// Parse the DOT string into an AST
|
|
155
|
+
const ast = parse(dotString);
|
|
156
|
+
|
|
157
|
+
// Remove dangerous attributes from the AST
|
|
158
|
+
sanitizeAST(ast);
|
|
159
|
+
|
|
160
|
+
// Convert back to DOT string
|
|
161
|
+
return stringify(ast);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
throw new Error(`Invalid DOT syntax: ${error.message}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Recursively sanitize AST nodes by removing dangerous attributes
|
|
169
|
+
*/
|
|
170
|
+
function sanitizeAST(node: any): void {
|
|
171
|
+
if (!node || typeof node !== 'object') return;
|
|
172
|
+
|
|
173
|
+
// Handle nodes with children
|
|
174
|
+
if (Array.isArray(node.children)) {
|
|
175
|
+
node.children = node.children.filter((child: any) => {
|
|
176
|
+
// Filter out dangerous attribute nodes
|
|
177
|
+
if (child.type === 'Attribute') {
|
|
178
|
+
const attributeName = child.key?.value;
|
|
179
|
+
if (DANGEROUS_ATTRIBUTES.has(attributeName)) {
|
|
180
|
+
console.warn(`Removed dangerous attribute: ${attributeName}`);
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Recursively sanitize child nodes
|
|
185
|
+
sanitizeAST(child);
|
|
186
|
+
return true;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Usage example
|
|
192
|
+
const userUploadedDOT = `
|
|
193
|
+
digraph G {
|
|
194
|
+
node [image="/etc/passwd"];
|
|
195
|
+
node1 [label="Safe label"];
|
|
196
|
+
}
|
|
197
|
+
`;
|
|
198
|
+
|
|
199
|
+
const sanitizedDOT = validateAndSanitizeDOT(userUploadedDOT);
|
|
200
|
+
// Result: digraph G { node1 [label="Safe label"]; }
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Best Practices**:
|
|
204
|
+
- Use the default `dot` command when possible
|
|
205
|
+
- If you need to customize `dotCommand`, use a hardcoded path or environment variable controlled by the deployment environment
|
|
206
|
+
- Do not allow end-user input to control the configuration options
|
|
207
|
+
- Validate and sanitize DOT strings from untrusted sources before rendering
|
|
208
|
+
- Consider using a whitelist approach for allowed attributes when processing user-provided DOT files
|
|
209
|
+
- Run Graphviz in a restricted environment when handling untrusted input
|
|
210
|
+
|
|
96
211
|
## Contributors 👥
|
|
97
212
|
|
|
98
213
|
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
package/lib/types.d.ts
CHANGED
|
@@ -98,6 +98,10 @@ export interface CommonOptions {
|
|
|
98
98
|
suppressWarnings?: boolean;
|
|
99
99
|
/**
|
|
100
100
|
* Path of graphviz dot command.
|
|
101
|
+
*
|
|
102
|
+
* **This should be a trusted, hardcoded path in your application configuration. Do not derive this value from end-user input.**
|
|
103
|
+
*
|
|
104
|
+
* @defaultValue 'dot'
|
|
101
105
|
*/
|
|
102
106
|
dotCommand?: string;
|
|
103
107
|
attributes?: {
|
|
@@ -120,6 +124,8 @@ export interface CommonOptions {
|
|
|
120
124
|
scale?: number;
|
|
121
125
|
/**
|
|
122
126
|
* Use external library.
|
|
127
|
+
*
|
|
128
|
+
* **These should be trusted library names defined in your application code. Do not derive these values from end-user input.**
|
|
123
129
|
*/
|
|
124
130
|
library?: string[];
|
|
125
131
|
/**
|