
Research
/Security News
9 Malicious NuGet Packages Deliver Time-Delayed Destructive Payloads
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.
Former is a Go library for populating structs from HTTP form data using struct field tags. It simplifies the process of binding form data to Go structures with support for complex types, nested structures, and multipart forms.
formfield tags to map form fields to struct fieldsgo get github.com/omareloui/former
package main
import (
"net/http"
"github.com/omareloui/former"
)
type LoginForm struct {
Username string `formfield:"username"`
Password string `formfield:"password"`
Remember bool `formfield:"remember"`
}
func loginHandler(w http.ResponseWriter, r *http.Request) {
var form LoginForm
if err := former.Populate(r, &form); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Use form.Username, form.Password, form.Remember
}
string, boolint, int8, int16, int32, int64uint, uint8, uint16, uint32, uint64float32, float64Multiple values with the same field name are collected into slices:
type Form struct {
Tags []string `formfield:"tags"`
}
// Form data: tags=go&tags=web&tags=api
// Result: Tags = []string{"go", "web", "api"}
Fixed-size arrays are filled up to their capacity:
type Form struct {
Scores [3]int `formfield:"scores"`
}
// Form data: scores=95&scores=87&scores=92
// Result: Scores = [3]int{95, 87, 92}
Maps expect key:value format:
type Form struct {
Settings map[string]string `formfield:"settings"`
}
// Form data: settings=theme:dark&settings=lang:en
// Result: Settings = map[string]string{"theme": "dark", "lang": "en"}
Pointers are automatically initialized when values are present:
type Form struct {
OptionalField *string `formfield:"optional"`
}
Embedded structs without tags have their fields at the top level:
type Address struct {
Street string `formfield:"street"`
City string `formfield:"city"`
}
type Person struct {
Name string `formfield:"name"`
Address // embedded
}
// Form data: name=John&street=Main St&city=NYC
Use dot notation for nested struct fields:
type Order struct {
Billing Address `formfield:"billing"`
Shipping Address `formfield:"shipping"`
}
// Form data: billing.street=123 Main&billing.city=NYC&shipping.street=456 Oak&shipping.city=LA
Nested structs can be populated from JSON strings:
type User struct {
Profile Profile `formfield:"profile"`
}
// Form data: profile={"age":30,"bio":"Gopher"}
Use the - tag to skip fields:
type Form struct {
Public string `formfield:"public"`
Private string `formfield:"-"` // This field is ignored
}
Former recognizes common checkbox values:
type Form struct {
Subscribe bool `formfield:"subscribe"`
}
// Any of these values result in true: "true", "on", "1"
Handle multipart file uploads:
func uploadHandler(w http.ResponseWriter, r *http.Request) {
// Parse form first
var form struct {
Title string `formfield:"title"`
}
if err := former.Populate(r, &form); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Get uploaded file
file, header, err := former.GetFile(r, "document")
if err != nil {
http.Error(w, "File required", http.StatusBadRequest)
return
}
defer file.Close()
// Process file...
}
type RegistrationForm struct {
// Basic fields
Username string `formfield:"username"`
Email string `formfield:"email"`
Password string `formfield:"password"`
Age int `formfield:"age"`
// Multiple selections
Interests []string `formfield:"interests"`
// Nested struct
Address struct {
Street string `formfield:"street"`
City string `formfield:"city"`
Country string `formfield:"country"`
} `formfield:"address"`
// Map for dynamic fields
Social map[string]string `formfield:"social"`
// Boolean field
Subscribe bool `formfield:"subscribe"`
}
func registerHandler(w http.ResponseWriter, r *http.Request) {
var form RegistrationForm
if err := former.Populate(r, &form); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Form is populated and ready to use
}
<form method="POST" action="/register">
<input name="username" type="text" />
<input name="email" type="email" />
<input name="password" type="password" />
<input name="age" type="number" />
<select name="interests" multiple>
<option value="coding">Coding</option>
<option value="music">Music</option>
<option value="sports">Sports</option>
</select>
<input name="address.street" type="text" />
<input name="address.city" type="text" />
<input name="address.country" type="text" />
<input name="social" value="twitter:@username" />
<input name="social" value="github:username" />
<input name="subscribe" type="checkbox" />
<button type="submit">Register</button>
</form>
Former follows these principles:
if err := former.Populate(r, &form); err != nil {
// Handle error - likely a type conversion issue
log.Printf("Form parsing error: %v", err)
http.Error(w, "Invalid form data", http.StatusBadRequest)
return
}
Former uses reflection to populate structs, which has some overhead. For best performance:
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)This project is licensed under the MIT License - see the LICENSE file for details.
FAQs
Unknown package
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.