|
45 | 45 | import org.owasp.esapi.codecs.JSONCodec; |
46 | 46 | import org.owasp.esapi.errors.EncodingException; |
47 | 47 | import org.owasp.esapi.errors.IntrusionException; |
| 48 | +import org.owasp.esapi.errors.ConfigurationException; |
| 49 | +import org.owasp.esapi.errors.NotConfiguredByDefaultException; |
| 50 | + |
| 51 | +import static org.owasp.esapi.PropNames.ACCEPTED_UNSAFE_METHOD_NAMES; |
| 52 | +import static org.owasp.esapi.PropNames.ACCEPTED_UNSAFE_METHODS_JUSTIFICATION; |
48 | 53 |
|
49 | 54 |
|
50 | 55 | /** |
@@ -271,11 +276,75 @@ public String encodeForVBScript(String input) { |
271 | 276 | return vbScriptCodec.encode(IMMUNE_VBSCRIPT, input); |
272 | 277 | } |
273 | 278 |
|
| 279 | + /////////////////////////////////////////////////////////////////////// |
| 280 | + // TODO - Move this method to some utility class (where?) when we |
| 281 | + // are ready to use it on other methods than just encodeForSQL. |
| 282 | + // |
| 283 | + // At that time, also move the method ESAPI.isMethodExplicityEnabled |
| 284 | + // to the same utility class. |
| 285 | + /** |
| 286 | + * Utility class to throw {@code NotConfiguredByDefaultException} if the |
| 287 | + * specified method name is not enabled by default. |
| 288 | + * |
| 289 | + * @param fullyQualifiedMethodName is the method name that we are checkig if |
| 290 | + * enabled in ESAPI.properties. |
| 291 | + * @param customAuditMsg is a audit message to log and use in exceptions. If |
| 292 | + * this value passed in is {@code null} or the string |
| 293 | + * "<default>", then a canned message is used to |
| 294 | + * compose the error message. |
| 295 | + * @param seeAlso is a string that provides additional reference for context |
| 296 | + * such as a CVE ID, GHAS Security Advisory, or ESAPI Security Bulletin. |
| 297 | + * @throws NotConfiguredByDefaultException if the specified method name is |
| 298 | + * not listed in the property <b>ESAPI.dangerouslyAllowUnsafeMethods.methodNames</b> |
| 299 | + * in the <b>ESAPI.properties</b> file. |
| 300 | + */ |
| 301 | + private void ensureDangerousMethodExplicitlyEnabled(String fullyQualifiedMethodName, |
| 302 | + String customAuditMsg, |
| 303 | + String seeAlso) { |
| 304 | + |
| 305 | + String auditMsg = null; |
| 306 | + if ( customAuditMsg == null || customAuditMsg.equalsIgnoreCase("<default>") ) { |
| 307 | + // Special case. Compose an audit message from a canned template. |
| 308 | + // TODO: Null / empty check for 'seeAlso'. |
| 309 | + auditMsg = "SIEM ALERT: Method '" + fullyQualifiedMethodName + "' has been invoked despite having credible " + |
| 310 | + "security concerns; for additional details, see " + seeAlso + "."; |
| 311 | + } else { |
| 312 | + auditMsg = customAuditMsg; // Use the custom audit message |
| 313 | + } |
| 314 | + |
| 315 | + if ( ! ESAPI.isMethodExplicityEnabled( fullyQualifiedMethodName ) ) { |
| 316 | + throw new NotConfiguredByDefaultException( "Method not explicitly enabled in property " + |
| 317 | + ACCEPTED_UNSAFE_METHOD_NAMES + "; " + auditMsg ); |
| 318 | + } else { |
| 319 | + String justification = null; |
| 320 | + try { |
| 321 | + // This throws a ConfigurationException (rather than returning null if |
| 322 | + // the property name is not found so we need to handle that. |
| 323 | + justification = ESAPI.securityConfiguration().getStringProp( ACCEPTED_UNSAFE_METHODS_JUSTIFICATION ); |
| 324 | + } catch ( ConfigurationException cex ) { |
| 325 | + logger.debug( Logger.EVENT_FAILURE, "Property " + ACCEPTED_UNSAFE_METHODS_JUSTIFICATION + " not found."); |
| 326 | + justification = "None"; |
| 327 | + } |
| 328 | + |
| 329 | + if ( justification == null || justification.trim().isEmpty() ) { |
| 330 | + justification = "None"; |
| 331 | + } |
| 332 | + logger.warning( Logger.EVENT_FAILURE, auditMsg + " Provided justification: " + justification ); |
| 333 | + } |
| 334 | + return; |
| 335 | + } |
| 336 | + |
274 | 337 |
|
275 | 338 | /** |
276 | 339 | * {@inheritDoc} |
277 | 340 | */ |
278 | 341 | public String encodeForSQL(Codec codec, String input) { |
| 342 | + |
| 343 | + // This will throw if this method is not explicitly enabled in ESAPI.properties. |
| 344 | + ensureDangerousMethodExplicitlyEnabled( DefaultEncoder.class.getName() + ".encodeForSQL", |
| 345 | + "<default>", |
| 346 | + "see CVE-2025-????? and ESAPI Security Bulletin #13 for details" ); |
| 347 | + |
279 | 348 | if( input == null ) { |
280 | 349 | return null; |
281 | 350 | } |
|
0 commit comments