Sling Academy
Home/Golang/Escaping Special Characters in Strings for HTML and SQL in Go

Escaping Special Characters in Strings for HTML and SQL in Go

Last updated: November 24, 2024

When working with strings that are intended to be displayed as HTML or used in SQL queries, it's essential to escape special characters. This is to ensure that they're rendered correctly in web browsers and to prevent SQL injection attacks, respectively.

Escaping HTML in Go

To escape special characters in strings for HTML rendering, you can use the html/template package in Go. Here’s how you can get started:

Basic Example

package main

import (
    "html/template"
    "os"
)

func main() {
    const tpl = `<p>Hello, {{.}}</p>`
    t := template.Must(template.New("escape").Parse(tpl))
    t.Execute(os.Stdout, " World & Friends")  // Escaped Output: <p>Hello,  World & Friends</p>
}

Intermediate Example

When dealing with dynamic content, you can use template's automatic escaping:

package main

import (
    "html/template"
    "os"
)

type Data struct {
    Name string
    Message string
}

func main() {
    const text = `<h1>Welcome, {{.Name}}!</h1><p>Message: {{.Message}}</p>`
    t := template.Must(template.New("dynamic").Parse(text))
    data := Data{
        Name: "Alice & Bob",
        Message: "Hello & Welcome!" 
    }
    t.Execute(os.Stdout, data)  // Name and Message will be escaped correctly
}

The automatic escaping feature of html/template ensures that any HTML special characters within {{.Name}} and {{.Message}} are safely escaped.

Escaping SQL in Go

To escape strings for SQL queries, we can use parameterized queries with Go's database/sql package. This is a crucial technique as it helps prevent SQL injection.

Basic Example

package main

import (
    "database/sql"
    "log"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    name := "Harvey \" Danger"
    result, err := db.Exec("INSERT INTO users (name) VALUES (?)", name)
    if err != nil {
        log.Fatal(err)
    }
    id, err := result.LastInsertId()
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Inserted new user with ID %d", id)
}

Intermediate Example

Using prepared statements can enhance performance and safety, especially with repeated query execution:

package main

import (
    "database/sql"
    "log"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    stmt, err := db.Prepare("INSERT INTO users (name) VALUES (?)")
    if err != nil {
        log.Fatal(err)
    }
    defer stmt.Close()

    names := []string{"Alice", "Bob & Charlie", "Dana \" Duncan"}
    for _, name := range names {
        _, err = stmt.Exec(name)
        if err != nil {
            log.Fatal(err)
        }
    }
}

Prepared statements keep you safe from SQL injection attacks by treating the inputs as data rather than executable code.

Advanced Concepts

For more complex scenarios, such as cleaning data that is both part of HTML content and SQL, you may consider implementing a mixed strategy or using a library designed for sanitizing inputs.

As you use these tools and techniques, always remember the nuances required for both HTML and SQL strings to be correctly formatted and secure.

Next Article: Handling Non-ASCII Characters in Go Strings

Previous Article: Managing Strings Safely with Concurrency in Go

Series: Working with Strings in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant