How does STR-Transform works? - language-agnostic

How does the STR-Transform transformation algorithm works for XML Signature, when working with WS Security? I need to sign the SecurityTokenReference used for the signature on a SOAP message, and this is the required transformation for the security token. I am using an x509 certificate to do the signature, so the security token is this certificate. However, in the message I only need the reference to the certificate thumbprint.
Here is the signature structure that I need to replicate, and the only bit that I am missing is the signature reference to the SecurityTokenReference:
<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<dsig:SignedInfo>
<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<dsig:Reference URI="#Timestamp_C1Ih1AB1vpPT5uG2">
<dsig:Transforms>
<dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<dsig:DigestValue>fVSyToUO8yS131cV8oT1h6fa69Jvtt+pKFeP4BFf1P4=</dsig:DigestValue>
</dsig:Reference>
<!-- Other signature references -->
<dsig:Reference URI="#str_U1sjQ5j8JtKnObLk">
<dsig:Transforms>
<dsig:Transform Algorithm="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform">
<wsse:TransformationParameters>
<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</wsse:TransformationParameters>
</dsig:Transform>
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<dsig:DigestValue>gRa3zakGn13XISoKpekB3zl0iDqb/LmNy7+aMDtzKIY=</dsig:DigestValue>
</dsig:Reference>
</dsig:SignedInfo>
<dsig:SignatureValue>ptO...E9Q==</dsig:SignatureValue>
<dsig:KeyInfo>
<wsse:SecurityTokenReference
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="str_U1sjQ5j8JtKnObLk">
<wsse:KeyIdentifier
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">h5...ow=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</dsig:KeyInfo>
</dsig:Signature>
Can someone explain me how to do the signature for such token? The step-by-step description of the algorithm, or an example using any language/library will be good.
In this document is the description of the transformation, from page 38, but I am unable to understand how to apply it in practice.

OK, after checking Oracle's WebLogic server debug and verbose log file having a working service example and setting the flags -Dweblogic.xml.crypto.dsig.debug=true -Dweblogic.xml.crypto.dsig.verbose=true -Dweblogic.xml.crypto.keyinfo.debug=true -Dweblogic.xml.crypto.keyinfo.verbose=true -Dweblogic.wsee.verbose=* -Dweblogic.wsee.debug=* (more info here, here, here and here), thank God there was a preety good insight on how the security token was de-referenced. Basically, having a SecurityTokenReference for an x509 certificate, with a KeyIdentifier, is dereferenced as a BinarySecurityToken in this way:
<wsse:BinarySecurityToken xmlns="" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">CertificateBase64String</wsse:BinarySecurityToken>
Some important things to notice are:
The ValueType, and thus the content of the BinarySecurityToken, is defined by the TokenType of the SecurityTokenReference. In this case, the text of the BinarySecurityToken is the x509 certificate that is referenced by the KeyIdentifier element, encoded as a base64 string.
According to the specification, the BinarySecurityToken only includes the ValueType attribute. So it should not include the EncodingType attribute, neither the Id attribute that the SecurityTokenReference has.
The same namespace prefix of the SecurityTokenReference is used. Also, the namespace for this prefix is included in the tag.
The default namespace attribute is set as empty: xmlns=""
So basically the whole SecurityTokenReference element is replaced by the new BinarySecurityToken, and this is the one to be canonicalized and hashed (to get its digest value). Beware that it is canonicalized and digested as is, so the operation may provide a wrong result if the XML is simplified by removing the empty xmlns namespace or the prefix namespace, or by changing the namespace prefix.
The example BinarySecurityToken is already canonicalized using the algorithm "http://www.w3.org/2001/10/xml-exc-c14n#", so in .NET, to get the DigestValue using the digest algorithm "http://www.w3.org/2001/04/xmlenc#sha256", is enough to do this:
System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create();
byte[] hash = sha.ComputeHash(Encoding.UTF8.GetBytes("<wsse:BinarySecurityToken xmlns=\"\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" ValueType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3\">MIIF...2A8=</wsse:BinarySecurityToken>"));
string digestValue = Convert.ToBase64String(hash);

Related

Is there XSS risk when using a template literal with an untrusted string to set an attribute value?

I'm building an iframe, not with innerHTML, but with createElement.. I have two untrusted strings that are used:
iframeEl.title = untrustedStr1;
iframeEl.src = `http://example.com/?id=${untrustedStr2}`;
According to the OWASP XSS cheatsheet, the title attribute is totally safe, so I'm not worried about that.
However, I'm not 100% sure about the iframeEl.src case.
I'm thinking about the 5 significant characters that typically need to be encoded: <, >, &, ", and ' and I don't see any way to escape out of the template literal. And I also don't see a mechanism to have untrustedStr2 run as JavaScript. (For example, if untrustedStr2 = 'document.cookie', it's interpolated as a string, not via evaluation).
I suppose if untrustedStr2 is a getter method somehow, I could have a problem. But if it's absolutely a string, this is safe and I don't need to encode, not even for the 5 significant characters. Is that right?
When working with the DOM, there are no html encoding issues in any element properties. The characters <, >, &, ", and ' do not need escaping.
However, you still need to deal with the semantics of the respective attribute. While title is just a plain string that's not used for anything but displaying tooltips, others are not safe:
on… event handlers contain javascript code. It's a bad practice to assign strings to them anyway, but if you do, interpolating values must follow javascript escaping rules.
⇨ Rule #3
style properties contain CSS rules which need their own escaping.
⇨ Rule #4
src or href attributes are urls that the browser will load at some point. Those definitely are sensitive, and when interpolating values into urls you need to follow URL encoding rules.
⇨ Rule #5
… (not meant to be exhaustive)
In your particular case, if you fail to url-encode the untrustedStr2, the attacker may send arbitrary query parameters or fragments to example.com. This is not a security issue in itself if example.com isn't susceptible to reflected XSS (the attacker may send the same link to the user via other channels), but it is broken functionality (undesired behaviour), but still it's your page endorsing the linked content.
So if untrustedStr2 is meant as a value of the id URI query parameter, you should definitely use
iframeEl.src = `http://example.com/?id=${encodeURIComponent(untrustedStr2)}`;
// ^^^^^^^^^^^^^^^^^^
It seems unlikely for untrustedStr2 to evaluate and/or break out of the string. However if you don't encode it you may allow "HTTP Parameter Pollution (HPP)".
// untrustedStr2 = '9&id=42';
iframeEl.src = `http://example.com/?id=${untrustedStr2}`;
By itself, this is not necessarily an indication of vulnerability. However, if the developer is not aware of the problem, the presence of duplicated parameters may produce an anomalous behavior in the application that can be potentially exploited by an attacker. As often in security, unexpected behaviors are a usual source of weaknesses that could lead to HTTP Parameter Pollution attacks in this case.
See https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/07-Input_Validation_Testing/04-Testing_for_HTTP_Parameter_Pollution.html
Or you could allow an attempt at a CSRF attack:
// untrustedStr2 = '9&action=delete';
iframeEl.src = `http://example.com/?id=${untrustedStr2}`;
I think it would be safer to encode it.

Codeeffects - Cannot load rule on UI that has In Rule Method with more than 255 string parameter value

It seems that CodeEffect library 4.3.2.6 has an issue with rule XML editing ON UI and transformation back from stroage to show it on UI for editing when rule XML has In Rule method call with string parameter that has string value passed in longer than 255 characters.
Is it made intentionally to avoid long rules to be edited on UI or just a bug so someone knows workaround for it?
To avoid any side effects from my code I downloaded and used Business Rule code example from codeeffects site Code Effects Demo Projects and opened it in VS2015.
In "Patient.cs" file added following code to
public class Patient
{
...
// In Rule Method that accepts only one string parameter
[Method("[NumberOfSegments]")]
public int RuleMethod01(
// explicitly specify maximum string allowed
[Parameter(ValueInputType.User,Max = 10000)]
string val)
{
return val.Split(',').Length;
}
}
On UI(using Ajax controller) I attempted to create rule with long string parameter passed in (in real project I need such long string since it contains unique parameters for In Rule method to use for calculations and cannot rely on the data sources approach that CodeEffects can offer)
Check if [NumberOfSegments] ("1111,2222,33333,4444,55555,6666,777,8888,999,0000,1111,222,333,44444,1231231,123123123,123123123,123123123,123123123,123123123,123123123,123123123,123123123,123132123,123123123,123123123,123123123,123123123,12123123,123123123,123123123,123123123,1231231233") greater than 12
But even that I explicitly specified maximum string length for parameter as 10000 in attribute Parameter UI does not allow me to enter string that has length more than 256 characters.
Documentation on CodeEffects site
Business-Rules-Data-Types does not mentioned any built-in restrictions and only way to restrict length of the string parameter use Parameter Attribute and its Max property.
Did anyone ran into the issue with such "synthetic" restrictions and can point me to the documentation or any workaround for that?
Thank you in advance for the any meaningful suggestions
PS: Just small update - when I manually edited Rule XML file and provided longer string as parameter (e.g. around 500 characters) I could not load it from the XML back to the UI the RuleEditor::Rule::InvalidElements collection contained one element with Hint property value "v122" dont know if its helpful but may be CodeEffects authors can know more about such Hint and what v122 means.
Strings longer than 255 chars (neither property values nor method params) are not supported in Code Effects. v122 is the error number that you get in response. Its original message is "The length of the value of this string element exceeds the maximum allowed limit".

Actionscript 3.0 Reg Exp Find first URL, Ignore Email

I've got a bit of code where I have a loop with a string.search() to parse a string of HTML. The purpose is to seek out any valid URLs and surround each one with HREF tags appropriately while ignoring anything else, like email addresses. The problem is no matter how I modify the regular expression, it either kicks back the part of the email address after the # sign and highlights it or it highlights or ignores everything.
An example string would be:
"</span><span class='blue'>Weaselgrease:</span><span class='magenta'>weaselgrease#weasel.grs vs weaselgrease.weasel.grs</span><span class='blue'> [12:41:33 AM]</span>"
Where 'weaselgrease.weasel.grs' would be identified as a proper URL and 'weaselgrease#weasel.grs' would be ignored.
The code I have currently is /([fh]t{1,2}ps?:\/\/)?[\w-]+\.\w{2,4}/
I know it's rather simple, but it doesn't need to be complex yet.
I've tried a conditional and gotten nowhere. I may just be missing something, but my searching and even playing legos with http://regex101.com/ has gotten me no closer.
Ultimately I'm going to have it do the following:
Identify a valid URL's index in the string
Ignore if it's an email
Ignore if it's just an IP address (no prepending http:// and no trailing slash)
But I'd be happy with just an inkling of help on what I need to do to get it to ignore email addresses.
URL without proper protocol (i.e. http, https, ftp) cannot be validated as such, because this means that almost everything that has . (dot) in it is a valid url.
So there is not a way to properly check if it's url or e-mail if you don't use the protocol. Example:
end of sentence.New sentence -> sentence.New is valid url in your case
weaselgrease#weasel.grs -> everything before # is ignored and weasel.grs is valid url

How to identify path/file/url in href

I'm trying to grab the href value in <a> HTML tags using Nokogiri.
I want to identify whether they are a path, file, URL, or even a <div> id.
My current work is:
hrefvalue = []
html.css('a').each do |atag|
hrefvalue << atag['href']
end
The possible values in a href might be:
somefile.html
http://www.someurl.com/somepath/somepath
/some/path/here
#previous
Is there a mechanism to identify whether the value is a valid full URL, or file, or path or others?
try URI:
require 'uri'
URI.parse('somefile.html').path
=> "somefile.html"
URI.parse('http://www.someurl.com/somepath/somepath').path
=> "/somepath/somepath"
URI.parse('/some/path/here').path
=> "/some/path/here"
URI.parse('#previous').path
=> ""
Nokogiri is often used with ruby's URI or open-uri, so if that's the case in your situation you'll have access to its methods. You can use that to attempt to parse the URI (using URI.parse). You can also generally use URI.join(base_uri, retrieved_href) to construct the full url, provided you've stored the base_uri.
(Edit/side-note: further details on using URI.join are available here: https://stackoverflow.com/a/4864170/624590 ; do note that URI.join that takes strings as parameters, not URI objects, so coerce where necessary)
Basically, to answer your question
Is there a mechanism to identify whether the value is a valid full
url, or file, or path or others?
If the retrieved_href and the base_uri are well formed, and retrieved_href == the joined pair, then it's an absolute path. Otherwise it's relative (again, assuming well formed inputs).
If you use URI to parse the href values, then apply some heuristics to the results, you can figure out what you want to know. This is basically what a browser has to do when it's about to send a request for a page or a resource.
Using your sample strings:
%w[
somefile.html
http://www.someurl.com/somepath/somepath
/some/path/here
#previous
].each do |u|
puts URI.parse(u).class
end
Results in:
URI::Generic
URI::HTTP
URI::Generic
URI::Generic
The only one that URI recognizes as a true HTTP URI is "http://www.someurl.com/somepath/somepath". All the others are missing the scheme "http://". (There are many more schemes you could encounter. See the specification for more information.)
Of the generic URIs, you can use some rules to sort through them so you'd know how to react if you have to open them.
If you gathered the HREF strings by scraping a page, you can assume it's safe to use the same scheme and host if the URI in question doesn't supply one. So, if you initially loaded "http://www.someurl.com/index.html", you could use "http://www.someurl.com/" as your basis for further requests.
From there, look inside the strings to determine whether they are anchors, absolute or relative paths. If the string:
Starts with # it's an anchor and would be applied to the current page without any need to reload it.
Doesn't contain a path delimiter /, it's a filename and would be added to the currently retrieved URL, substituting the file name, and retrieved. A nice way to do the substitution is to use File.dirname , File.basename and File.join against the string.
Begins with a path delimiter it's an absolute path and is used to replace the path in the original URL. URI::split and URI::join are your friends here.
Doesn't begin with a path delimiter, it's a relative path and is added to the current URI similarly to #2.
Regarding:
hrefvalue = []
html.css('a').each do |atag|
hrefvalue << atag['href']
end
I'd use this instead:
hrefvalue = html.search('a').map { |a| a['href'] }
But that's just me.
A final note: URI has some problems with age and needs an update. It's a useful library but, for heavy-duty URI rippin' apart, I highly recommend looking into using Addressable/URI.

Should we overload the meaning of configuration settings?

Imagine an instance of some lookup of configuration settings called "configuration", used like this:
if(! string.IsNullOrEmpty(configuration["MySetting"])
{
DoSomethingWithTheValue(configuration["MySetting"]);
}
The meaning of the setting is overloaded. It means both "turn this feature on or off" and "here is a specific value to do something with". These can be decomposed into two settings:
if(configuration["UseMySetting"])
{
DoSomethingWithTheValue(configuration["MySetting"]);
}
The second approach seems to make configuration more complicated, but slightly easier to parse, and it separate out the two sorts of behaviour. The first seems much simpler at first but it's not clear what we choose as the default "turn this off" setting. "" might actually a valid value for MySetting.
Is there a general best practice rule for this?
I find the question to be slightly confusing, because it talks about (1) parsing, and (2) using configuration settings, but the code samples are for only the latter. That confusion means that my answer might be irrelevant to what you intended to ask. Anyway...
I suggest an approach that is illustrated by the following pseudo-code API (comments follow afterwards):
class Configuration
{
void parse(String fileName);
boolean exists(String name);
String lookupString(String name);
String lookupString(String name, String defaultValue);
int lookupInt(String name);
int lookupInt(String name, int defaultValue);
float lookupFloat(String name);
float lookupFloat(String name, float defaultValue);
boolean lookupBoolean(String name);
boolean lookupBoolean(String name, boolean defaultValue);
... // more pairs of lookup<Type>() operations for other types
}
The parse() operation parses a configuration file and stores the parsed data in a convenient format, for example, in a map or hash-table. (If you want, parse() can delegate the parsing to a third-party library, for example, a parser for XML, Java Properties, JSON, .ini files or whatever.)
After parsing is complete, your application can invoke the other operations to retrieve/use the configuration settings.
A lookup<Type>() operation retrieves the value of the specified name and parses it into the specified type (and throws an exception if the parsing fails). There are two overloadings for each lookup<Type>() operation. The version with one parameter throws an exception if the specified variable does not exist. The version with an extra parameter (denoting a default value) returns that default value if the specified variable does not exist.
The exists() operation can be used to test whether a specified name exists in the configuration file.
The above pseudo-code API offers two benefits. First, it provides type-safe access to configuration data (which wasn't a stated requirement in your question, but I think it is important anyway). Second, it enables you to distinguish between "variable is not defined in configuration" and "variable is defined but its value happens to be an empty string".
If you have already committed yourself to a particular configuration syntax, then just implement the above Configuration class as a thin wrapper around a parser for the existing configuration syntax. If you haven't already chosen a configuration syntax and if your project is in C++ or Java, then you might want to look at my Config4* library, which provides a ready-to-use implementation of the above pseudo-code class (with a few extra bells and whistles).