mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2026-11-13 05:41:25 -10:00
Pass scan options through rendering, variables, matchers, and extractors so resolve(), public_ip()/publicip(), and jarm() honor -lna and -eh. These helpers previously performed network I/O outside the scan's network policy. Use the scan dialer for HTTP and JARM connections and reject restricted IP addresses in DNS answers. Validate original and normalized hostnames to prevent exclusion bypasses through DNS escapes and trailing dots. Enforce -eh with or without -lna, including in unsigned templates. Keep local access available without -lna unless excluded, and preserve configured DNS resolvers, including local ones. Bind helpers at evaluation time without storing scan state in cached expressions. Reject network helper calls without initialized scan context. Fixes #7769 Signed-off-by: Dwi Siswanto <[email protected]>
124 lines
2.5 KiB
Go
124 lines
2.5 KiB
Go
package variables
|
|
|
|
import "github.com/projectdiscovery/nuclei/v3/pkg/types"
|
|
|
|
// Scope contains values used while evaluating template variables.
|
|
//
|
|
// Data values are terminal values from runtime, options, constants, payloads,
|
|
// or protocol context. Template values are produced from the template variables
|
|
// section and may be re-rendered when later data becomes available.
|
|
type Scope struct {
|
|
values map[string]scopeValue
|
|
options *types.Options
|
|
}
|
|
|
|
type scopeValueKind uint8
|
|
|
|
const (
|
|
scopeValueData scopeValueKind = iota
|
|
scopeValueTemplate
|
|
)
|
|
|
|
type scopeValue struct {
|
|
value interface{}
|
|
kind scopeValueKind
|
|
}
|
|
|
|
// NewScope creates an empty variable evaluation scope.
|
|
func NewScope() *Scope {
|
|
return &Scope{values: make(map[string]scopeValue)}
|
|
}
|
|
|
|
// WithOptions binds this scope to the current scan without adding template variables.
|
|
func (s *Scope) WithOptions(options *types.Options) *Scope {
|
|
s.options = options
|
|
return s
|
|
}
|
|
|
|
// AddData adds terminal data values to the scope.
|
|
func (s *Scope) AddData(values ...map[string]interface{}) *Scope {
|
|
if s == nil {
|
|
return s
|
|
}
|
|
|
|
for _, valueMap := range values {
|
|
for key, value := range valueMap {
|
|
s.AddDataValue(key, value)
|
|
}
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
// AddDataValue adds one terminal data value to the scope.
|
|
func (s *Scope) AddDataValue(key string, value interface{}) *Scope {
|
|
if s == nil {
|
|
return s
|
|
}
|
|
|
|
s.values[key] = scopeValue{value: value, kind: scopeValueData}
|
|
|
|
return s
|
|
}
|
|
|
|
// AddTemplate adds values produced from template variables.
|
|
func (s *Scope) AddTemplate(values map[string]interface{}) *Scope {
|
|
if s == nil {
|
|
return s
|
|
}
|
|
|
|
for key, value := range values {
|
|
s.AddTemplateValue(key, value)
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
// AddTemplateValue adds one value produced from template variables.
|
|
func (s *Scope) AddTemplateValue(key string, value interface{}) *Scope {
|
|
if s == nil {
|
|
return s
|
|
}
|
|
|
|
s.values[key] = scopeValue{value: value, kind: scopeValueTemplate}
|
|
|
|
return s
|
|
}
|
|
|
|
// Values returns a plain value map for render evaluation.
|
|
func (s *Scope) Values() map[string]interface{} {
|
|
if s == nil || len(s.values) == 0 {
|
|
return nil
|
|
}
|
|
|
|
values := make(map[string]interface{}, len(s.values))
|
|
for key, value := range s.values {
|
|
values[key] = value.value
|
|
}
|
|
|
|
return values
|
|
}
|
|
|
|
func (s *Scope) clone() *Scope {
|
|
if s == nil {
|
|
return NewScope()
|
|
}
|
|
|
|
clone := NewScope().WithOptions(s.options)
|
|
for key, value := range s.values {
|
|
clone.values[key] = value
|
|
}
|
|
|
|
return clone
|
|
}
|
|
|
|
func (s *Scope) get(key string) (scopeValue, bool) {
|
|
if s == nil {
|
|
return scopeValue{}, false
|
|
}
|
|
|
|
value, ok := s.values[key]
|
|
|
|
return value, ok
|
|
}
|