fix(05): WR-02 fill Encrypted columns from plaintext, never Scan request input
This commit is contained in:
@@ -122,6 +122,9 @@ func setField(field reflect.Value, val any) error {
|
||||
field.Set(converted)
|
||||
return nil
|
||||
}
|
||||
if field.Type() == encryptedType {
|
||||
return err
|
||||
}
|
||||
if field.CanAddr() {
|
||||
if scanner, ok := field.Addr().Interface().(sql.Scanner); ok {
|
||||
scanSrc, scanErr := fillScanSource(val)
|
||||
@@ -147,7 +150,12 @@ func fillScanSource(val any) (any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
var encryptedType = reflect.TypeOf(Encrypted{})
|
||||
|
||||
func convertValue(src reflect.Value, destType reflect.Type) (reflect.Value, error) {
|
||||
if destType == encryptedType {
|
||||
return encryptedFromRequest(src)
|
||||
}
|
||||
if src.Type().AssignableTo(destType) {
|
||||
return src, nil
|
||||
}
|
||||
@@ -156,3 +164,17 @@ func convertValue(src reflect.Value, destType reflect.Type) (reflect.Value, erro
|
||||
}
|
||||
return reflect.Value{}, fmt.Errorf("cannot assign %s to %s", src.Type(), destType)
|
||||
}
|
||||
|
||||
// encryptedFromRequest treats request input for an Encrypted column as
|
||||
// plaintext. It never falls through to Encrypted.Scan: Scan decrypts, so a
|
||||
// write path that scanned request input would reject real secrets and accept
|
||||
// another row's ciphertext, copying that row's secret.
|
||||
func encryptedFromRequest(src reflect.Value) (reflect.Value, error) {
|
||||
if src.Type() == encryptedType {
|
||||
return src, nil
|
||||
}
|
||||
if src.Kind() != reflect.String {
|
||||
return reflect.Value{}, fmt.Errorf("encrypted value must be a string")
|
||||
}
|
||||
return reflect.ValueOf(NewEncrypted(src.String())), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user