Vous êtes sur la page 1sur 24

SignIn/Register Help Country

Products
OracleTechnologyNetwork

Solutions

Communities

Downloads

Iama...

Store

Iwantto...

Support

Search

Training

Partners

Java

SecureCodingGuidelinesforJavaSE

UpdatedforJavaSE8
Documentversion:5.1
Published:02April2014
Lastupdated:19November2015

Introduction
[+]0Fundamentals
[+]1DenialofService
[+]2ConfidentialInformation
[+]3InjectionandInclusion
[+]4AccessibilityandExtensibility
[+]5InputValidation
[+]6Mutability
[+]7ObjectConstruction
[+]8SerializationandDeserialization
[+]9AccessControl
Conclusion
References
[+]AppendixA:DefensiveuseoftheJavaNativeInterface(JNI)
Introduction
OneofthemaindesignconsiderationsfortheJavaplatformistoprovideasecureenvironmentforexecutingmobilecode.Javacomeswithitsown
uniquesetofsecuritychallenges.WhiletheJavasecurityarchitecture[1]canprotectusersandsystemsfromhostileprogramsdownloadedovera
network,itcannotdefendagainstimplementationbugsthatoccurintrustedcode.Suchbugscaninadvertentlyopentheveryholesthatthesecurity
architecturewasdesignedtocontain,includingaccesstofiles,printers,webcams,microphones,andthenetworkfrombehindfirewalls.Insevere
caseslocalprogramsmaybeexecutedorJavasecuritydisabled.Thesebugscanpotentiallybeusedtoturnthemachineintoazombiecomputer,
stealconfidentialdatafrommachineandintranet,spythroughattacheddevices,preventusefuloperationofthemachine,assistfurtherattacks,and
manyothermaliciousactivities.
Thechoiceoflanguagesystemimpactstherobustnessofanysoftwareprogram.TheJavalanguage[2]andvirtualmachine[3]providemany
featurestomitigatecommonprogrammingmistakes.Thelanguageistypesafe,andtheruntimeprovidesautomaticmemorymanagementand
boundscheckingonarrays.Javaprogramsandlibrariescheckforillegalstateattheearliestopportunity.ThesefeaturesalsomakeJavaprograms
highlyresistanttothestacksmashing[4]andbufferoverflowattackspossibleintheCandtoalesserextentC++programminglanguages.These
attackshavebeendescribedasthesinglemostperniciousproblemincomputersecuritytoday[5].TheexplicitstatictypingofJavamakescode
easytounderstand(andfacilitatesstaticanalysis),andthedynamicchecksensureunexpectedconditionsresultinpredictablebehaviourwhich
makesJavaajoytouse.
Tominimizethelikelihoodofsecurityvulnerabilitiescausedbyprogrammererror,Javadevelopersshouldadheretorecommendedcoding
guidelines.Existingpublications,suchasEffectiveJava[6],provideexcellentguidelinesrelatedtoJavasoftwaredesign.Others,suchasSoftware
Security:BuildingSecurityIn[7],outlineguidingprinciplesforsoftwaresecurity.Thispaperbridgessuchpublicationstogetherandincludes
coverageofadditionaltopics.ThisdocumentprovidesamorecompletesetofsecurityspecificcodingguidelinestargetedattheJava
programminglanguage.TheseguidelinesareofinteresttoallJavadevelopers,whethertheycreatetrustedenduserapplicationsandapplets,
implementtheinternalsofasecuritycomponent,ordevelopsharedJavaclasslibrariesthatperformcommonprogrammingtasks.Any
implementationbugcanhaveserioussecurityramificationsandcouldappearinanylayerofthesoftwarestack.
Whilesections0through3aregenerallyapplicableacrossdifferenttypesofsoftware,mostoftheguidelinesinsections4through9focuson
applicationsthatinteractwithuntrustedcode(thoughsomeguidelinesinthesesectionsarestillrelevantforothersituations).Developersshould
analyzetheinteractionsthatoccuracrossanapplication'strustboundariesandidentifythetypesofdatainvolvedtodeterminewhichguidelines
arerelevant.Performingthreatmodelingandestablishingtrustboundariescanhelptoaccomplishthis(seeGuideline04).
Theseguidelinesareintendedtohelpdevelopersbuildsecuresoftware,buttheydonotfocusspecificallyonsoftwarethatimplementssecurity
features.Therefore,topicssuchascryptographyarenotcoveredinthisdocument(see[9]and[10]forinformationonusingcryptographywith
Java).Whileaddingfeaturestosoftwarecansolvesomesecurityrelatedproblems,itshouldnotbereliedupontoeliminatesecuritydefects.
ThisdocumenthasbeenupdatedtocoversomeofthenewfeaturesincludedinJavaSE8.However,theseguidelinesarealsoapplicableto
softwarewrittenforpreviousversionsofJava.
0Fundamentals
ThefollowinggeneralprinciplesapplythroughoutJavasecurity.
Guideline00/FUNDAMENTALS0:Prefertohaveobviouslynoflawsratherthannoobviousflaws[8]
Creatingsecurecodeisnotnecessarilyeasy.DespitetheunusuallyrobustnatureofJava,flawscanslippastwithsurprisingease.Designand
writecodethatdoesnotrequirecleverlogictoseethatitissafe.Specifically,followtheguidelinesinthisdocumentunlessthereisaverystrong
reasonnotto.
Guideline01/FUNDAMENTALS1:DesignAPIstoavoidsecurityconcerns
ItisbettertodesignAPIswithsecurityinmind.TryingtoretrofitsecurityintoanexistingAPIismoredifficultanderrorprone.Forexample,makinga
classfinalpreventsamalicioussubclassfromaddingfinalizers,cloning,andoverridingrandommethods(Guideline45).Anyuseofthe
SecurityManagerhighlightsanareathatshouldbescrutinized.
Guideline02/FUNDAMENTALS2:Avoidduplication
Duplicationofcodeanddatacausesmanyproblems.Bothcodeanddatatendnottobetreatedconsistentlywhenduplicated,e.g.,changesmay

About

OTN

notbeappliedtoallcopies.
Guideline03/FUNDAMENTALS3:Restrictprivileges
Despitebestefforts,notallcodingflawswillbeeliminatedeveninwellreviewedcode.However,ifthecodeisoperatingwithreducedprivileges,
thenexploitationofanyflawsislikelytobethwarted.Themostextremeformofthisisknownastheprincipleofleastprivilege.UsingtheJava
securitymechanismthiscanbeimplementedstaticallybyrestrictingpermissionsthroughpolicyfilesanddynamicallywiththeuseofthe
java.security.AccessController.doPrivilegedmechanism(seesection9).
RichInternetApplications(RIA)canspecifytheirrequestedpermissionsviaanappletparameterorintheJNLP.Asignedjarcanalsoincludea
manifestattributethatspecifieswhetheritmustruninasandboxorwithallpermissions(see[11]).Ifasandboxedappletorapplicationattemptsto
executesecuritysensitivecode,theJREwillthrowasecurityexception.RIAsshouldfollowtheprincipleofleastprivilege,andshouldbe
configuredtorunwiththeleastamountofnecessarypermissions.RunningaRIAwithallpermissionsshouldbeavoidedwheneverpossible.
Guideline04/FUNDAMENTALS4:Establishtrustboundaries
Inordertoensurethatasystemisprotected,itisnecessarytoestablishtrustboundaries.Datathatcrossestheseboundariesshouldbesanitized
andvalidatedbeforeuse.Trustboundariesarealsonecessarytoallowsecurityauditstobeperformedefficiently.Codethatensuresintegrityof
trustboundariesmustitselfbeloadedinsuchawaythatitsownintegrityisassured.
Forinstance,awebbrowserisoutsideofthesystemforawebserver.Equally,awebserverisoutsideofthesystemforawebbrowser.Therefore,
webbrowserandserversoftwareshouldnotrelyuponthebehavioroftheotherforsecurity.
Whenauditingtrustboundaries,therearesomequestionsthatshouldbekeptinmind.Arethecodeanddatausedsufficientlytrusted?Coulda
librarybereplacedwithamaliciousimplementation?Isuntrustedconfigurationdatabeingused?Iscodecallingwithlowerprivilegesadequately
protectedagainst?
Guideline05/FUNDAMENTALS5:Minimisethenumberofpermissionchecks
Javaisprimarilyanobjectcapabilitylanguage.SecurityManagerchecksshouldbeconsideredalastresort.Performsecuritychecksatafew
definedpointsandreturnanobject(acapability)thatclientcoderetainssothatnofurtherpermissionchecksarerequired.
Guideline06/FUNDAMENTALS6:Encapsulate
Allocatebehaviorsandprovidesuccinctinterfaces.Fieldsofobjectsshouldbeprivateandaccessorsavoided.Theinterfaceofamethod,class,
package,andmoduleshouldformacoherentsetofbehaviors,andnomore.
Guideline07/FUNDAMENTALS7:Documentsecurityrelatedinformation
APIdocumentationshouldcoversecurityrelatedinformationsuchasrequiredpermissions,securityrelatedexceptions,callersensitivity(see
Guidelines98through911foradditionalonthistopic),andanypreconditionsorpostconditionsthatarerelevanttosecurity.Documentingthis
informationincommentsforatoolsuchasJavaDoccanalsohelptoensurethatitiskeptuptodate.
1DenialofService
Inputintoasystemshouldbecheckedsothatitwillnotcauseexcessiveresourceconsumptiondisproportionatetothatusedtorequesttheservice.
CommonaffectedresourcesareCPUcycles,memory,diskspace,andfiledescriptors.
Inrarecasesitmaynotbepracticaltoensurethattheinputisreasonable.Itmaybenecessarytocarefullycombinetheresourcecheckingwiththe
logicofprocessingthedata.Forclientsystemsitisgenerallylefttotheusertoclosetheapplicationifitisusingexcessiveresources.Therefore,
onlyattacksresultinginpersistentDoS,suchaswastingsignificantdiskspace,needbedefendedagainst.Serversystemsshouldberobust
againstexternalattacks.
Guideline11/DOS1:Bewareofactivitiesthatmayusedisproportionateresources
Examplesofattacksinclude:
Requestingalargeimagesizeforvectorgraphics.Forinstance,SVGandfontfiles.
Integeroverflowerrorscancausesanitycheckingofsizestofail.
Anobjectgraphconstructedbyparsingatextorbinarystreammayhavememoryrequirementsmanytimesthatoftheoriginaldata.
"Zipbombs"wherebyashortfileisveryhighlycompressed.Forinstance,ZIPs,GIFsandgzipencodedHTTPcontents.Whendecompressingfiles
itisbettertosetlimitsonthedecompresseddatasizeratherthanrelyinguponcompressedsizeormetadata.
"Billionlaughsattack"wherebyXMLentityexpansioncausesanXMLdocumenttogrowdramaticallyduringparsing.Setthe
XMLConstants.FEATURE_SECURE_PROCESSINGfeaturetoenforcereasonablelimits.
Causingmanykeystobeinsertedintoahashtablewiththesamehashcode,turninganalgorithmofaroundO(n)intoO(n2 ).
Regularexpressionsmayexhibitcatastrophicbacktracking.
XPathexpressionsmayconsumearbitraryamountsofprocessortime.
JavadeserializationandJavaBeansXMLdeserializationofmaliciousdatamayresultinunboundedmemoryorCPUusage.
Detailedloggingofunusualbehaviormayresultinexcessiveoutputtologfiles.
Infiniteloopscanbecausedbyparsingsomecornercasedata.Ensurethateachiterationofaloopmakessomeprogress.
Guideline12/DOS2:Releaseresourcesinallcases
Someobjects,suchasopenfiles,locksandmanuallyallocatedmemory,behaveasresourceswhichrequireeveryacquireoperationtobepaired
withadefiniterelease.Itiseasytooverlookthevastpossibilitiesforexecutionspathswhenexceptionsarethrown.Resourcesshouldalwaysbe
releasedpromptlynomatterwhat.
Evenexperiencedprogrammersoftenhandleresourcesincorrectly.Inordertoreduceerrors,duplicationshouldbeminimizedandresource
handlingconcernsshouldbeseparated.TheExecuteAroundMethodpatternprovidesanexcellentwayofextractingthepairedacquireand
releaseoperations.ThepatterncanbeusedconciselyusingtheJavaSE8lambdafeature.
longsum=readFileBuffered(InputStreamin>{
longcurrent=0;
for(;;){
intb=in.read();
if(b==1){
returncurrent;
}
current+=b;
}
});
ThetrywithresourcesyntaxintroducedinJavaSE7automaticallyhandlesthereleaseofmanyresourcetypes.
publicRreadFileBuffered(

InputStreamHandlerhandler
)throwsIOException{
try(finalInputStreamin=Files.newInputStream(path)){
handler.handle(newBufferedInputStream(in));
}
}

Forresourceswithoutsupportfortheenhancedfeature,usethestandardresourceacquisitionandrelease.Attemptstorearrangethisidiom
typicallyresultinerrorsandmakesthecodesignificantlyhardertofollow.
publicRlocked(Actionaction){
lock.lock();
try{
returnaction.run();
}finally{
lock.unlock();
}
}
Ensurethatanyoutputbuffersareflushedinthecasethatoutputwasotherwisesuccessful.Iftheflushfails,thecodeshouldexitviaanexception.
publicvoidwriteFile(
OutputStreamHandlerhandler
)throwsIOException{
try(finalOutputStreamrawOut=Files.newOutputStream(path)){
finalBufferedOutputStreamout=
newBufferedOutputStream(rawOut);
handler.handle(out);
out.flush();
}
}
Somedecoratorsofresourcesmaythemselvesberesourcesthatrequirecorrectrelease.Forinstance,inthecurrentOpenJDKimplementation
compressionrelatedstreamsarenativelyimplementedusingtheCheapforbufferstorage.Caremustbetakenthatbothresourcesarereleasedin
allcircumstances.
publicvoidbufferedWriteGzipFile(
OutputStreamHandlerhandler
)throwsIOException{
try(
finalOutputStreamrawOut=Files.newOutputStream(path);
finalOutputStreamcompressedOut=
newGzipOutputStream(rawOut);
){
finalBufferedOutputStreamout=
newBufferedOutputStream(compressedOut);
handler.handle(out);
out.flush();
}
}
Guideline13/DOS3:Resourcelimitchecksshouldnotsufferfromintegeroverflow
TheJavalanguageprovidesboundscheckingonarrayswhichmitigatesthevastmajorityofintegeroverflowattacks.However,someoperations
onprimitiveintegraltypessilentlyoverflow.Therefore,takecarewhencheckingresourcelimits.Thisisparticularlyimportantonpersistent
resources,suchasdiskspace,wherearebootmaynotcleartheproblem.
Somecheckingcanberearrangedsoastoavoidoverflow.Withlargevalues,current+maxcouldoverflowtoanegativevalue,whichwould
alwaysbelessthanmax.
privatevoidcheckGrowBy(longextra){
if(extra<0||current>maxextra){
thrownewIllegalArgumentException();
}
}
Ifperformanceisnotaparticularissue,averboseapproachistousearbitrarysizedintegers.
privatevoidcheckGrowBy(longextra){
BigIntegercurrentBig=BigInteger.valueOf(current);
BigIntegermaxBig=BigInteger.valueOf(max);
BigIntegerextraBig=BigInteger.valueOf(extra);
if(extra<0||
currentBig.add(extraBig).compareTo(maxBig)>0){
thrownewIllegalArgumentException();
}
}
Apeculiarityoftwo'scomplementintegerarithmeticisthattheminimumnegativevaluedoesnothaveamatchingpositivevalueofthesame
magnitude.So,Integer.MIN_VALUE==Integer.MIN_VALUE,Integer.MIN_VALUE==Math.abs(Integer.MIN_VALUE)and,forinteger
a,a<0doesnotimplya>0.ThesameedgecaseoccursforLong.MIN_VALUE.
AsofJavaSE8,thejava.lang.Mathclassalsocontainsmethodsforvariousoperations(e.g.addExact,multiplyExact,decrementExact,
etc.)thatthrowanArithmeticExceptioniftheresultoverflowsthegiventype.
2ConfidentialInformation
Confidentialdatashouldbereadableonlywithinalimitedcontext.Datathatistobetrustedshouldnotbeexposedtotampering.Privilegedcode
shouldnotbeexecutablethroughintendedinterfaces.
Guideline21/CONFIDENTIAL1:Purgesensitiveinformationfromexceptions
Exceptionobjectsmayconveysensitiveinformation.Forexample,ifamethodcallsthejava.io.FileInputStreamconstructortoreadan
underlyingconfigurationfileandthatfileisnotpresent,ajava.io.FileNotFoundExceptioncontainingthefilepathisthrown.Propagatingthis

exceptionbacktothemethodcallerexposesthelayoutofthefilesystem.Manyformsofattackrequireknowingorguessinglocationsoffiles.
Exposingafilepathcontainingthecurrentuser'snameorhomedirectoryexacerbatestheproblem.SecurityManagerchecksguardthis
informationwhenitisincludedinstandardsystemproperties(suchasuser.home)andrevealingitinexceptionmessageseffectivelyallowsthese
checkstobebypassed.
Internalexceptionsshouldbecaughtandsanitizedbeforepropagatingthemtoupstreamcallers.Thetypeofanexceptionmayrevealsensitive
information,evenifthemessagehasbeenremoved.Forinstance,FileNotFoundExceptionrevealswhetherornotagivenfileexists.
Itissometimesalsonecessarytosanitizeexceptionscontaininginformationderivedfromcallerinputs.Forexample,exceptionsrelatedtofile
accesscoulddisclosewhetherafileexists.Anattackermaybeablegatherusefulinformationbyprovidingvariousfilenamesasinputand
analyzingtheresultingexceptions.
Becarefulwhendependingonanexceptionforsecuritybecauseitscontentsmaychangeinthefuture.Supposeapreviousversionofalibrarydid
notincludeapotentiallysensitivepieceofinformationintheexception,andanexistingclientrelieduponthatforsecurity.Forexample,alibrary
maythrowanexceptionwithoutamessage.Anapplicationprogrammermaylookatthisbehavioranddecidethatitisokaytopropagatethe
exception.However,alaterversionofthelibrarymayaddextradebugginginformationtotheexceptionmessage.Theapplicationexposesthis
additionalinformation,eventhoughtheapplicationcodeitselfmaynothavechanged.Onlyincludeknown,acceptableinformationfroman
exceptionratherthanfilteringoutsomeelementsoftheexception.
Exceptionsmayalsoincludesensitiveinformationabouttheconfigurationandinternalsofthesystem.Donotpassexceptioninformationtoend
usersunlessoneknowsexactlywhatitcontains.Forexample,donotincludeexceptionstacktracesinsideHTMLcomments.
Guideline22/CONFIDENTIAL2:Donotloghighlysensitiveinformation
Someinformation,suchasSocialSecuritynumbers(SSNs)andpasswords,ishighlysensitive.Thisinformationshouldnotbekeptforlongerthan
necessarynorwhereitmaybeseen,evenbyadministrators.Forinstance,itshouldnotbesenttologfilesanditspresenceshouldnotbe
detectablethroughsearches.Sometransientdatamaybekeptinmutabledatastructures,suchaschararrays,andclearedimmediatelyafteruse.
ClearingdatastructureshasreducedeffectivenessontypicalJavaruntimesystemsasobjectsaremovedinmemorytransparentlytothe
programmer.
Thisguidelinealsohasimplicationsforimplementationanduseoflowerlevellibrariesthatdonothavesemanticknowledgeofthedatatheyare
dealingwith.Asanexample,alowlevelstringparsinglibrarymaylogthetextitworkson.AnapplicationmayparseanSSNwiththelibrary.This
createsasituationwheretheSSNsareavailabletoadministratorswithaccesstothelogfiles.
Guideline23/CONFIDENTIAL3:Considerpurginghighlysensitivefrommemoryafteruse
Tonarrowthewindowwhenhighlysensitiveinformationmayappearincoredumps,debugging,andconfidentialityattacks,itmaybeappropriate
tozeromemorycontainingthedataimmediatelyafteruseratherthanwaitingforthegarbagecollectionmechanism.
However,doingsodoeshavenegativeconsequences.Codequalitywillbecompromisedwithextracomplicationsandmutabledatastructures.
Librariesmaymakecopies,leavingthedatainmemoryanyway.Theoperationofthevirtualmachineandoperatingsystemmayleavecopiesof
thedatainmemoryorevenondisk.
3InjectionandInclusion
Averycommonformofattackinvolvescausingaparticularprogramtointerpretdatacraftedinsuchawayastocauseanunanticipatedchangeof
control.Typically,butnotalways,thisinvolvestextformats.
Guideline31/INJECT1:Generatevalidformatting
Attacksusingmaliciouslycraftedinputstocauseincorrectformattingofoutputsarewelldocumented[7].Suchattacksgenerallyinvolveexploiting
specialcharactersinaninputstring,incorrectescaping,orpartialremovalofspecialcharacters.
Iftheinputstringhasaparticularformat,combiningcorrectionandvalidationishighlyerrorprone.Parsingandcanonicalizationshouldbedone
beforevalidation.Ifpossible,rejectinvaliddataandanysubsequentdata,withoutattemptingcorrection.Forinstance,manynetworkprotocolsare
vulnerabletocrosssitePOSTattacks,byinterpretingtheHTTPbodyeventhoughtheHTTPheadercauseserrors.
Usewelltestedlibrariesinsteadofadhoccode.TherearemanylibrariesforcreatingXML.CreatingXMLdocumentsusingrawtextiserrorprone.
Forunusualformatswhereappropriatelibrariesdonotexist,suchasconfigurationfiles,createclassesthatcleanlyhandleallformattingandonly
formattingcode.
Guideline32/INJECT2:AvoiddynamicSQL
ItiswellknownthatdynamicallycreatedSQLstatementsincludinguntrustedinputaresubjecttocommandinjection.Thisoftentakestheformof
supplyinganinputcontainingaquotecharacter(')followedbySQL.AvoiddynamicSQL.
ForparameterisedSQLstatementsusingJavaDatabaseConnectivity(JDBC),usejava.sql.PreparedStatementor
java.sql.CallableStatementinsteadofjava.sql.Statement.Ingeneral,itisbettertouseawellwritten,higherlevellibrarytoinsulate
applicationcodefromSQL.Whenusingsuchalibrary,itisnotnecessarytolimitcharacterssuchasquote(').IftextdestinedforXML/HTMLis
handledcorrectlyduringoutput(Guideline33),thenitisunnecessarytodisallowcharacterssuchaslessthan(<)ininputstoSQL.
AnexampleofusingPreparedStatementcorrectly:
Stringsql="SELECT*FROMUserWHEREuserId=?";
PreparedStatementstmt=con.prepareStatement(sql);
stmt.setString(1,userId);
ResultSetrs=prepStmt.executeQuery();
Guideline33/INJECT3:XMLandHTMLgenerationrequirescare
UntrusteddatashouldbeproperlysanitizedbeforebeingincludedinHTMLorXMLoutput.Failuretoproperlysanitizethedatacanleadtomany
differentsecurityproblems,suchasCrossSiteScripting(XSS)andXMLInjectionvulnerabilities.Itisimportanttobeparticularlycarefulwhen
usingJavaServerPages(JSP).
Therearemanydifferentwaystosanitizedatabeforeincludingitinoutput.Charactersthatareproblematicforthespecifictypeofoutputcanbe
filtered,escaped,orencoded.Alternatively,charactersthatareknowntobesafecanbeallowed,andeverythingelsecanbefiltered,escaped,or
encoded.Thislatterapproachispreferable,asitdoesnotrequireidentifyingandenumeratingallcharactersthatcouldpotentiallycauseproblems.
Implementingcorrectdatasanitizationandencodingcanbetrickyanderrorprone.Therefore,itisbettertousealibrarytoperformthesetasks
duringHTMLorXMLconstruction.
Guideline34/INJECT4:Avoidanyuntrusteddataonthecommandline

Whencreatingnewprocesses,donotplaceanyuntrusteddataonthecommandline.Behaviorisplatformspecific,poorlydocumented,and
frequentlysurprising.Maliciousdatamay,forinstance,causeasingleargumenttobeinterpretedasanoption(typicallyaleadingonUnixor/
onWindows)orastwoseparatearguments.Anydatathatneedstobepassedtothenewprocessshouldbepassedeitherasencodedarguments
(e.g.,Base64),inatemporaryfile,orthroughainheritedchannel.
Guideline35/INJECT5:RestrictXMLinclusion
XMLDocumentTypeDefinitions(DTDs)allowURLstobedefinedassystementities,suchaslocalfilesandHTTPURLswithinthelocalintranetor
localhost.XMLExternalEntity(XXE)attacksinsertlocalfilesintoXMLdatawhichmaythenbeaccessibletotheclient.Similarattacksmaybe
madeusingXInclude,theXSLTdocumentfunction,andtheXSLTimportandincludeelements.Thesafewaytoavoidtheseproblemswhilst
maintainingthepowerofXMListoreduceprivilegesasdescribedinGuideline92.Youmaydecidetogivesomeaccessthroughthistechnique,
suchasinclusiontopagesfromthesameoriginwebsite.Anotherapproach,ifsuchanAPIisavailable,istosetallentityresolverstosafe
implementations.
NotethatthisissuegenerallyappliestotheuseofAPIsthatuseXMLbutarenotspecificallyXMLAPIs.
Guideline36/INJECT6:CarewithBMPfiles
BMPimagesfilesmaycontainreferencestolocalICC(InternationalColorConsortium)files.WhilstthecontentsofICCfilesisunlikelytobe
interesting,theactofattemptingtoreadfilesmaybeanissue.EitheravoidBMPfiles,orreduceprivilegesasGuideline92.
Guideline37/INJECT7:DisableHTMLdisplayinSwingcomponents
ManySwingpluggablelookandfeelsinterprettextincertaincomponentsstartingwith<html>asHTML.Ifthetextisfromanuntrustedsource,an
adversarymaycrafttheHTMLsuchthatothercomponentsappeartobepresentortoperforminclusionattacks.
TodisabletheHTMLrenderfeature,setthe"html.disable"clientpropertyofeachcomponenttoBoolean.TRUE(nootherBooleantrue
instancewilldo).
label.putClientProperty("html.disable",true);
Guideline38/INJECT8:Takecareinterpretinguntrustedcode
Codecanbehiddeninanumberofplaces.Ifthesourceisnottrustedtosupplycode,thenasecuresandboxmustbeconstructedtorunitin.Some
examplesofcomponentsorAPIsthatcanpotentiallyexecuteuntrustedcodeinclude:
Scriptsrunthroughthejavax.scriptscriptingAPIorsimilar.
LiveConnectinterfaceswithJavaScriptrunninginthebrowser.TheJavaScriptrunningonawebpagewillnotusuallyhavebeenverifiedwithan
objectcodesigningcertificate.
BydefaulttheOracleimplementationoftheXSLTinterpreterenablesextensionstocallJavacode.Setthe
javax.xml.XMLConstants.FEATURE_SECURE_PROCESSINGfeaturetodisableit.
LongTermPersistenceofJavaBeansComponentssupportsexecutionofJavastatements.
JavaSoundwillloadcodethroughthejavax.sound.midi.MidiSystem.getSoundbankmethods.
RMImayallowloadingofremotecodespecifiedbyremoteconnection.OntheOracleJDK,thisisdisabledbydefaultbutmaybeenabledor
disabledthroughthejava.rmi.server.useCodebaseOnlysystemproperty.
LDAP(RFC2713)allowsloadingofremotecodeinaserverresponse.OntheOracleJDK,thisisdisabledbydefaultbutmaybeenabledor
disabledthroughthecom.sun.jndi.ldap.object.trustURLCodebasesystemproperty.
ManySQLimplementationsallowexecutionofcodewitheffectsoutsideofthedatabaseitself.
Guideline39/INJECT9:Preventinjectionofexceptionalfloatingpointvalues
Workingwithfloatingpointnumbersrequirescarewhenimportingthosefromoutsideofatrustboundary,astheNaN(notanumber)orinfinite
valuescanbeinjectedintoapplicationsviauntrustedinputdata,forexamplebyconversionof(untrusted)Stringsconvertedbythe
Double.valueOfmethod.Unfortunatelytheprocessingofexceptionalvaluesistypicallynotimmediatelynoticedwithoutintroducingsanitization
code.Moreover,passinganexceptionalvaluetoanoperationpropagatestheexceptionalnumericstatetotheoperationresult.
Bothpositiveandnegativeinfinitityvaluesarepossibleoutcomesofafloatingpointoperation[2],whenresultsbecometoohighortoolowtobe
representablebythememoryareathatbacksaprimitivefloatingpointvalue.Also,theexceptionalvalueNaNcanresultfromdividing0.0by0.0or
subtractinginfinityfrominfinity.
Theresultsofcastingpropagatedexceptionalfloatingpointnumberstoshort,integerandlongprimitivevaluesneedspecialcare,too.Thisis
becauseanintegerconversionofaNaNvaluewillresultina0,andapositiveinfinitevalueistransformedtoInteger.MAX_VALUE(or
Integer.MIN_VALUEfornegativeinfinity),whichmaynotbecorrectincertainusecases.
Therearedistinctapplicationscenarioswheretheseexceptionalvaluesareexpected,suchasscientificdataanalysiswhichreliesonnumeric
processing.However,itisadvisedthattheresultvaluesbecontainedforthatpurposeinthelocalcomponent.Thiscanbeachievedbysanitizing
anyfloatingpointresultsbeforepassingthembacktothegenericpartsofanapplication.
Asmentionedbefore,theprogrammermaywishtoincludesanitizationcodefortheseexceptionalvalueswhenworkingwithfloatingpoint
numbers,especiallyifrelatedtoauthorizationorauthenticationdecisions,orforwardingfloatingpointvaluestoJNI.TheDoubleandFloat
classeshelpwithsanitizationbyprovidingtheisNanandisInfinitemethods.AlsokeepinmindthatcomparinginstancesofDouble.NaNvia
theequalityoperatoralwaysresultstobefalse,whichmaycauselookupproblemsinmapsorcollectionswhenusingtheequalityoperatorona
wrappeddoublefieldwithintheequalsmethodinaclassdefinition.
Atypicalcodepatternthatcanblockfurtherprocessingofunexpectedfloatingpointnumbersisshowninthefollowingexamplesnippet.
if(Double.isNaN(untrusted_double_value)){
//specificactionfornonnumbercase
}
if(Double.isInfinite(untrusted_double_value)){
//specificactionforinfinitecase
}
//normalprocessingstartshere
4AccessibilityandExtensibility
Thetaskofsecuringasystemismadeeasierbyreducingthe"attacksurface"ofthecode.
Guideline41/EXTEND1:Limittheaccessibilityofclasses,interfaces,methods,andfields
AJavapackagecomprisesagroupingofrelatedJavaclassesandinterfaces.Declareanyclassorinterfacepublicifitisspecifiedaspartofa
publishedAPI,otherwise,declareitpackageprivate.Similarly,declareclassmembersandconstructors(nestedclasses,methods,orfields)public

orprotectedasappropriate,iftheyarealsopartoftheAPI.Otherwise,declarethemprivateorpackageprivatetoavoidexposingthe
implementation.Notethatmembersofinterfacesareimplicitlypublic.
Classesloadedbydifferentloadersdonothavepackageprivateaccesstooneanothereveniftheyhavethesamepackagename.Classesinthe
samepackageloadedbythesameclassloadermusteithersharethesamecodesigningcertificateornothaveacertificateatall.IntheJava
virtualmachineclassloadersareresponsiblefordefiningpackages.Itisrecommendedthat,asamatterofcourse,packagesaremarkedas
sealedinthejarfilemanifest.
Guideline42/EXTEND2:Limittheaccessibilityofpackages
Containersmayhideimplementationcodebyaddingtothepackage.accesssecurityproperty.Thispropertypreventsuntrustedclassesfrom
otherclassloaderslinkingandusingreflectiononthespecifiedpackagehierarchy.Caremustbetakentoensurethatpackagescannotbe
accessedbyuntrustedcontextsbeforethispropertyhasbeenset.
Thisexamplecodedemonstrateshowtoappendtothepackage.accesssecurityproperty.Notethatitisnotthreadsafe.Thiscodeshould
generallyonlyappearonceinasystem.
privatestaticfinalStringPACKAGE_ACCESS_KEY="package.access";
static{
StringpackageAccess=java.security.Security.getProperty(
PACKAGE_ACCESS_KEY
);
java.security.Security.setProperty(
PACKAGE_ACCESS_KEY,
(
(packageAccess==null||
packageAccess.trim().isEmpty())?
"":
(packageAccess+",")
)+
"xx.example.product.implementation."
);
}
Guideline43/EXTEND3:Isolateunrelatedcode
Containers,thatistosaycodethatmanagescodewithalowerleveloftrust,shouldisolateunrelatedapplicationcode.Evenotherwiseuntrusted
codeistypicallygivenpermissionstoaccessitsorigin,andthereforeuntrustedcodefromdifferentoriginsshouldbeisolated.TheJavaPlugin,for
example,loadsunrelatedappletsintoseparateclassloaderinstancesandrunstheminseparatethreadgroups.
Althoughtheremaybesecuritychecksondirectaccesses,thereareindirectwaysofusingthesystemclassloaderandthreadcontextclass
loader.Programsshouldbewrittenwiththeexpectationthatthesystemclassloaderisaccessibleeverywhereandthethreadcontextclassloader
isaccessibletoallcodethatcanexecuteontherelevantthreads.
Someapparentlyglobalobjectsareactuallylocaltoappletorapplicationcontexts.Appletsloadedfromdifferentwebsiteswillhavedifferent
valuesreturnedfrom,forexample,java.awt.Frame.getFrames.Suchstaticmethods(andmethodsontrueglobals)useinformationfromthe
currentthreadandtheclassloadersofcodeonthestacktodeterminewhichisthecurrentcontext.Thispreventsmaliciousappletsfrominterfering
withappletsfromothersites.
Mutablestatics(seeGuideline611)andexceptionsarecommonwaysthatisolationisinadvertentlybreached.Mutablestaticsallowanycodeto
interferewithcodethatdirectlyor,morelikely,indirectlyusesthem.
Librarycodecanbecarefullywrittensuchthatitissafelyusablebylesstrustedcode.Librariesrequirealeveloftrustatleastequaltothecodeitis
usedbyinordernottoviolatetheintegrityoftheclientcode.Containersshouldensurethatlesstrustedcodeisnotabletoreplacemoretrusted
librarycodeanddoesnothavepackageprivateaccess.Bothrestrictionsaretypicallyenforcedbyusingaseparateclassloaderinstance,the
libraryclassloaderaparentoftheapplicationclassloader.
Guideline44/EXTEND4:LimitexposureofClassLoaderinstances
AccesstoClassLoaderinstancesallowscertainoperationsthatmaybeundesirable:
Accesstoclassesthatclientcodewouldnotnormallybeabletoaccess.
RetrieveinformationintheURLsofresources(actuallyopeningtheURLislimitedwiththeusualrestrictions).
Assertionstatusmaybeturnedonandoff.
Theinstancemaybecasttoasubclass.ClassLoadersubclassesfrequentlyhaveundesirablemethods.
Guideline98explainsaccesschecksmadeonacquiringClassLoaderinstancesthroughvariousJavalibrarymethods.Careshouldbetaken
whenexposingaclassloaderthroughthethreadcontextclassloader.
Guideline45/EXTEND5:Limittheextensibilityofclassesandmethods
Designclassesandmethodsforinheritanceordeclarethemfinal[6].Leftnonfinal,aclassormethodcanbemaliciouslyoverriddenbyan
attacker.Aclassthatdoesnotpermitsubclassingiseasiertoimplementandverifythatitissecure.Prefercompositiontoinheritance.

//Unsubclassableclasswithcomposedbehavior.
publicfinalclassSensitiveClass{
privatefinalBehaviorbehavior;
//Hideconstructor.
privateSensitiveClass(Behaviorbehavior){
this.behavior=behavior;
}
//Guardedconstruction.
publicstaticSensitiveClassnewSensitiveClass(
Behaviorbehavior
){
//...validateanyarguments...
//...performsecuritychecks...
returnnewSensitiveClass(behavior);
}
}

MalicioussubclassesthatoverridetheObject.finalizemethodcanresurrectobjectsevenifanexceptionwasthrownfromtheconstructor.
Lowlevelclasseswithconstructorsexplicitlythrowingajava.security.SecurityExceptionarelikelytohavesecurityissues.FromJDK6on,
anexceptionthrownbeforethejava.lang.Objectconstructorexitswhichpreventsthefinalizerfrombeingcalled.Therefore,ifsubclassingis
allowedandsecuritymanagerpermissionisrequiredtoconstructanobject,performthecheckbeforecallingthesuperconstructor.Thiscanbe
donebyinsertingamethodcallasanargumenttoanalternative("this")constructorinvocation.
publicclassNonFinal{
//soleaccessibleconstructor
publicNonFinal(){
this(securityManagerCheck());
}
privateNonFinal(Voidignored){
//...
}
privatestaticVoidsecurityManagerCheck(){
SecurityManagersm=System.getSecurityManager();
if(sm!=null){
sm.checkPermission(...);
}
returnnull;
}
}
ForcompatibilitywithversionsofJavapriortoJDK6,checkthattheclasshasbeeninitializedbeforeeverysensitiveoperationandbeforetrusting
anyotherinstanceoftheclass.Itmaybepossibletoseeapartiallyinitializedinstance,soanyvariableshouldhaveasafeinterpretationforthe
defaultvalue.Formutableclasses,itisadvisabletomakean"initialized"flagvolatiletocreateasuitablehappensbeforerelationship.
publicclassNonFinal{
privatevolatilebooleaninitialized;
//soleconstructor
publicNonFinal(){
securityManagerCheck();
//...initializeclass...
//Lastactionofconstructor.
this.initialized=true;
}
publicvoiddoSomething(){
checkInitialized();
}
privatevoidcheckInitialized(){
if(!initialized){
thrownewSecurityException(
"NonFinalnotinitialized"
);
}
}
}
Whenconfirminganobject'sclasstypebyexaminingthejava.lang.Classinstancebelongingtothatobject,donotcompareClassinstances
solelyusingclassnames(acquiredviaClass.getName),becauseinstancesarescopedbothbytheirclassnameaswellastheclassloaderthat
definedtheclass.
Guideline46/EXTEND6:Understandhowasuperclasscanaffectsubclassbehavior
Subclassesdonothavetheabilitytomaintainabsolutecontrolovertheirownbehavior.Asuperclasscanaffectsubclassbehaviorbychangingthe
implementationofaninheritedmethodthatisnotoverridden.Ifasubclassoverridesallinheritedmethods,asuperclasscanstillaffectsubclass
behaviorbyintroducingnewmethods.Suchchangestoasuperclasscanunintentionallybreakassumptionsmadeinasubclassandleadtosubtle
securityvulnerabilities.ConsiderthefollowingexamplethatoccurredinJDK1.2:
ClassHierarchyInheritedMethods

java.util.Hashtableput(key,val)
^remove(key)
|extends
|
java.util.Properties
^
|extends
|
java.security.Providerput(key,val)//SecurityManager
remove(key)//checksforthese
//methods
Theclassjava.security.Providerextendsfromjava.util.Properties,andPropertiesextendsfromjava.util.Hashtable.Inthis
hierarchy,theProviderclassinheritscertainmethodsfromHashtable,includingputandremove.Provider.putmapsacryptographic
algorithmname,likeRSA,toaclassthatimplementsthatalgorithm.Topreventmaliciouscodefromaffectingitsinternalmappings,Provider
overridesputandremovetoenforcethenecessarySecurityManagerchecks.
TheHashtableclasswasenhancedinJDK1.2toincludeanewmethod,entrySet,whichsupportstheremovalofentriesfromtheHashtable.
TheProviderclasswasnotupdatedtooverridethisnewmethod.ThisoversightallowedanattackertobypasstheSecurityManagercheck
enforcedinProvider.remove,andtodeleteProvidermappingsbysimplyinvokingtheHashtable.entrySetmethod.
TheprimaryflawisthatthedatabelongingtoProvider(itsmappings)isstoredintheHashtableclass,whereasthechecksthatguardthedata

areenforcedintheProviderclass.ThisseparationofdatafromitscorrespondingSecurityManagerchecksonlyexistsbecauseProvider
extendsfromHashtable.BecauseaProviderisnotinherentlyaHashtable,itshouldnotextendfromHashtable.Instead,theProviderclass
shouldencapsulateaHashtableinstanceallowingthedataandthechecksthatguardthatdatatoresideinthesameclass.Theoriginaldecision
tosubclassHashtablelikelyresultedfromanattempttoachievecodereuse,butitunfortunatelyledtoanawkwardrelationshipbetweena
superclassanditssubclasses,andeventuallytoasecurityvulnerability.
Malicioussubclassesmayimplementjava.lang.Cloneable.Implementingthisinterfaceaffectsthebehaviourofthesubclass.Acloneofa
victimobjectmaybemade.Theclonewillbeashallowcopy.Theintrinsiclockandfieldsofthetwoobjectswillbedifferent,butreferencedobjects
willbethesame.Thisallowsanadversarytoconfusethestateofinstancesoftheattackedclass.
JDK8introduceddefaultmethodsoninterfaces.Thesedefaultmethodsareanotherpathfornewandunexpectedmethodstoshowupinaclass.
Ifaclassimplementsaninterfacewithdefaultmethods,thosearenowpartoftheclassandmayallowunexpectedaccesstointernaldata.Fora
securitysensitiveclass,allinterfacesimplementedbytheclass(andallsuperclasses)wouldneedtobemonitoredaspreviouslydiscussed.
5InputValidation
AfeatureofthecultureofJavaisthatrigorousmethodparametercheckingisusedtoimproverobustness.Moregenerally,validatingexternal
inputsisanimportantpartofsecurity.
Guideline51/INPUT1:Validateinputs
Inputfromuntrustedsourcesmustbevalidatedbeforeuse.Maliciouslycraftedinputsmaycauseproblems,whethercomingthroughmethod
argumentsorexternalstreams.Examplesincludeoverflowofintegervaluesanddirectorytraversalattacksbyincluding"../"sequencesin
filenames.Easeofusefeaturesshouldbeseparatedfromprogrammaticinterfaces.Notethatinputvalidationmustoccurafteranydefensive
copyingofthatinput(seeGuideline62).
Guideline52/INPUT2:Validateoutputfromuntrustedobjectsasinput
Ingeneralmethodargumentsshouldbevalidatedbutnotreturnvalues.However,inthecaseofanupcall(invokingamethodofhigherlevelcode)
thereturnedvalueshouldbevalidated.Likewise,anobjectonlyreachableasanimplementationofanupcallneednotvalidateitsinputs.
Guideline53/INPUT3:Definewrappersaroundnativemethods
Javacodeissubjecttoruntimechecksfortype,arraybounds,andlibraryusage.Nativecode,ontheotherhand,isgenerallynot.WhilepureJava
codeiseffectivelyimmunetotraditionalbufferoverflowattacks,nativemethodsarenot.Tooffersomeoftheseprotectionsduringtheinvocationof
nativecode,donotdeclareanativemethodpublic.Instead,declareitprivateandexposethefunctionalitythroughapublicJavabasedwrapper
method.Awrappercansafelyperformanynecessaryinputvalidationpriortotheinvocationofthenativemethod:
publicfinalclassNativeMethodWrapper{
//privatenativemethod
privatenativevoidnativeOperation(byte[]data,intoffset,
intlen);
//wrappermethodperformschecks
publicvoiddoOperation(byte[]data,intoffset,intlen){
//copymutableinput
data=data.clone();
//validateinput
//Noteoffset+lenwouldbesubjecttointegeroverflow.
//Forinstanceifoffset=1andlen=Integer.MAX_VALUE,
//thenoffset+len==Integer.MIN_VALUEwhichislower
//thandata.length.
//Further,
//loopsoftheform
//for(inti=offset;i<offset+len;++i){...}
//wouldnotthrowanexceptionorcausenativecodeto
//crash.
if(offset<0||len<0||offset>data.lengthlen){
thrownewIllegalArgumentException();
}
nativeOperation(data,offset,len);
}
}
6Mutability
Mutability,whilstappearinginnocuous,cancauseasurprisingvarietyofsecurityproblems.
Guideline61/MUTABLE1:Preferimmutabilityforvaluetypes
Makingclassesimmutablepreventstheissuesassociatedwithmutableobjects(describedinsubsequentguidelines)fromarisinginclientcode.
Immutableclassesshouldnotbesubclassable.Further,hidingconstructorsallowsmoreflexibilityininstancecreationandcaching.Thismeans
makingtheconstructorprivateordefaultaccess("packageprivate"),orbeinginapackagecontrolledbythepackage.accesssecurityproperty.
ImmutableclassesthemselvesshoulddeclarefieldsfinalandprotectagainstanymutableinputsandoutputsasdescribedinGuideline62.
Constructionofimmutableobjectscanbemadeeasierbyprovidingbuilders(cf.EffectiveJava[6]).
Guideline62/MUTABLE2:Createcopiesofmutableoutputvalues
Ifamethodreturnsareferencetoaninternalmutableobject,thenclientcodemaymodifytheinternalstateoftheinstance.Unlesstheintentionis
tosharestate,copymutableobjectsandreturnthecopy.
Tocreateacopyofatrustedmutableobject,callacopyconstructorortheclonemethod:
publicclassCopyOutput{
privatefinaljava.util.Datedate;
...
publicjava.util.DategetDate(){
return(java.util.Date)date.clone();
}
}

Guideline63/MUTABLE3:Createsafecopiesofmutableandsubclassableinputvalues
Mutableobjectsmaybechangedafterandevenduringtheexecutionofamethodorconstructorcall.Typesthatcanbesubclassedmaybehave
incorrectly,inconsistently,and/ormaliciously.Ifamethodisnotspecifiedtooperatedirectlyonamutableinputparameter,createacopyofthat
inputandperformthemethodlogiconthecopy.Infact,iftheinputisstoredinafield,thecallercanexploitraceconditionsintheenclosingclass.
Forexample,atimeofcheck,timeofuseinconsistency(TOCTOU)[7]canbeexploitedwhereamutableinputcontainsonevalueduringa
SecurityManagercheckbutadifferentvaluewhentheinputisusedlater.
Tocreateacopyofanuntrustedmutableobject,callacopyconstructororcreationmethod:
publicfinalclassCopyMutableInput{
privatefinalDatedate;
//java.util.Dateismutable
publicCopyMutableInput(Datedate){
//createcopy
this.date=newDate(date.getTime());
}
}
Inrarecasesitmaybesafetocallacopymethodontheinstanceitself.Forinstance,java.net.HttpCookieismutablebutfinalandprovidesa
publicclonemethodforacquiringcopiesofitsinstances.
publicfinalclassCopyCookie{
//java.net.HttpCookieismutable
publicvoidcopyMutableInput(HttpCookiecookie){
//createcopy
cookie=(HttpCookie)cookie.clone();//HttpCookieisfinal
//performlogic(includingrelevantsecuritychecks)
//oncopy
doLogic(cookie);
}
}
ItissafetocallHttpCookie.clonebecauseitcannotbeoverriddenwithamaliciousimplementation.Datealsoprovidesapublicclonemethod,
butbecausethemethodisoverrideableitcanbetrustedonlyiftheDateobjectisfromatrustedsource.Someclasses,suchasjava.io.File,
aresubclassableeventhoughtheyappeartobeimmutable.
Thisguidelinedoesnotapplytoclassesthataredesignedtowrapatargetobject.Forinstance,java.util.Arrays.asListoperatesdirectlyon
thesuppliedarraywithoutcopying.
Insomecases,notablycollections,amethodmayrequireadeepercopyofaninputobjectthantheonereturnedviathatinput'scopyconstructoror
clonemethod.InstantiatinganArrayListwithacollection,forexample,producesashallowcopyoftheoriginalcollectioninstance.Boththe
copyandtheoriginalsharereferencestothesameelements.Iftheelementsaremutable,thenadeepcopyovertheelementsisrequired:
//Stringisimmutable.
publicvoidshallowCopy(Collection<String>strs){
strs=newArrayList<String>(strs);
doLogic(strs);
}
//Dateismutable.
publicvoiddeepCopy(Collection<Date>dates){
Collection<Date>datesCopy=newArrayList<Date>(dates.size());
for(Datedate:dates){
datesCopy.add(newjava.util.Date(date.getTime()));
}
doLogic(datesCopy);
}
Constructorsshouldcompletethedeepcopybeforeassigningvaluestoafield.Anobjectshouldneverbeinastatewhereitreferencesuntrusted
data,evenbriefly.Further,objectsassignedtofieldsshouldneverhavereferenceduntrusteddataduetothedangersofunsafepublication.
Guideline64/MUTABLE4:Supportcopyfunctionalityforamutableclass
Whendesigningamutablevalueclass,provideameanstocreatesafecopiesofitsinstances.Thisallowsinstancesofthatclasstobesafely
passedtoorreturnedfrommethodsinotherclasses(seeGuideline62andGuideline63).Thisfunctionalitymaybeprovidedbyastaticcreation
method,acopyconstructor,orbyimplementingapubliccopymethod(forfinalclasses).
Ifaclassisfinalanddoesnotprovideanaccessiblemethodforacquiringacopyofit,callerscouldresorttoperformingamanualcopy.This
involvesretrievingstatefromaninstanceofthatclassandthencreatinganewinstancewiththeretrievedstate.Mutablestateretrievedduringthis
processmustlikewisebecopiedifnecessary.Performingsuchamanualcopycanbefragile.Iftheclassevolvestoincludeadditionalstate,then
manualcopiesmaynotincludethatstate.
Thejava.lang.Cloneablemechanismisproblematicandshouldnotbeused.Implementingclassesmustexplicitlycopyallmutablefields
whichishighlyerrorprone.Copiedfieldsmaynotbefinal.Thecloneobjectmaybecomeavailablebeforefieldcopyinghascompleted,possiblyat
someintermediatestage.InnonfinalclassesObject.clonewillmakeanewinstanceofthepotentiallymalicioussubclass.Implementing
Cloneableisanimplementationdetail,butappearsinthepublicinterfaceoftheclass.
Guideline65/MUTABLE5:Donottrustidentityequalitywhenoverridableoninputreferenceobjects
Overridablemethodsmaynotbehaveasexpected.
Forinstance,whenexpectingidentityequalitybehavior,Object.equalsmaybeoverriddentoreturntruefordifferentobjects.Inparticularwhen
usedasakeyinaMap,anobjectmaybeabletopassitselfoffasadifferentobjectthatitshouldnothaveaccessto.
Ifpossible,useacollectionimplementationthatenforcesidentityequality,suchasIdentityHashMap.
privatefinalMap<Window,Extra>extras=newIdentityHashMap<>();
publicvoidop(Windowwindow){
//Window.equalsmaybeoverridden,
//butsafeasweareusingIdentityHashMap

Extraextra=extras.get(window);
}
Ifsuchacollectionisnotavailable,useapackageprivatekeywhichanadversarydoesnothaveaccessto.
publicclassWindow{
/*pp*/classPrivateKey{
//Optionally,refertorealobject.
/*pp*/WindowgetWindow(){
returnWindow.this;
}
}
/*pp*/finalPrivateKeyprivateKey=newPrivateKey();
privatefinalMap<Window.PrivateKey,Extra>extras=
newWeakHashMap<>();
...
}
publicclassWindowOps{
publicvoidop(Windowwindow){
//Window.equalsmaybeoverridden,
//butsafeaswedon'tuseit.
Extraextra=extras.get(window.privateKey);
...
}
}
Guideline66/MUTABLE6:Treatpassinginputtountrustedobjectasoutput
Theaboveguidelinesonoutputobjectsapplywhenpassedtountrustedobjects.Appropriatecopyingshouldbeapplied.
privatefinalbyte[]data;
publicvoidwriteTo(OutputStreamout)throwsIOException{
//Copy(clone)privatemutabledatabeforesending.
out.write(data.clone());
}
Acommonbutdifficulttospotcaseoccurswhenaninputobjectisusedasakey.Acollection'suseofequalitymaywellexposeotherelementstoa
maliciousinputobjectonorafterinsertion.
Guideline67/MUTABLE7:Treatoutputfromuntrustedobjectasinput
Theaboveguidelinesoninputobjectsapplywhenreturnedfromuntrustedobjects.Appropriatecopyingandvalidationshouldbeapplied.
privatefinalDatestart;
privateDateend;
publicvoidendWith(Eventevent)throwsIOException{
Dateend=newDate(event.getDate().getTime());
if(end.before(start)){
thrownewIllegalArgumentException("...");
}
this.end=end;
}
Guideline68/MUTABLE8:Definewrappermethodsaroundmodifiableinternalstate
Ifastatethatisinternaltoaclassmustbepubliclyaccessibleandmodifiable,declareaprivatefieldandenableaccesstoitviapublicwrapper
methods.Ifthestateisonlyintendedtobeaccessedbysubclasses,declareaprivatefieldandenableaccessviaprotectedwrappermethods.
Wrappermethodsallowinputvalidationtooccurpriortothesettingofanewvalue:
publicfinalclassWrappedState{
//privateimmutableobject
privateStringstate;
//wrappermethod
publicStringgetState(){
returnstate;
}
//wrappermethod
publicvoidsetState(finalStringnewState){
this.state=requireValidation(newState);
}
privatestaticStringrequireValidation(finalStringstate){
if(...){
thrownewIllegalArgumentException("...");
}
returnstate;
}
}
MakeadditionaldefensivecopiesingetStateandsetStateiftheinternalstateismutable,asdescribedinGuideline62.
Wherepossiblemakemethodsforoperationsthatmakesenseinthecontextoftheinterfaceoftheclassratherthanmerelyexposinginternal
implementation.
Guideline69/MUTABLE9:Makepublicstaticfieldsfinal
Callerscantriviallyaccessandmodifypublicnonfinalstaticfields.Neitheraccessesnormodificationscanbeguardedagainst,andnewlyset
valuescannotbevalidated.Fieldswithsubclassabletypesmaybesettoobjectswithmaliciousimplementations.Alwaysdeclarepublicstatic
fieldsasfinal.

publicclassFiles{
publicstaticfinalStringseparator="/";
publicstaticfinalStringpathSeparator=":";
}
Ifusinganinterfaceinsteadofaclass,themodifiers"publicstaticfinal"canbeomittedtoimprovereadability,astheconstantsareimplicitly
public,static,andfinal.Constantscanalternativelybedefinedusinganenumdeclaration.
Protectedstaticfieldssufferfromthesameproblemastheirpublicequivalentsbutalsotendtoindicateconfuseddesign.
Guideline610/MUTABLE10:Ensurepublicstaticfinalfieldvaluesareconstants
Onlyimmutablevaluesshouldbestoredinpublicstaticfields.Manytypesaremutableandareeasilyoverlooked,inparticulararraysand
collections.Mutableobjectsthatarestoredinafieldwhosetypedoesnothaveanymutatormethodscanbecastbacktotheruntimetype.Enum
valuesshouldneverbemutable.
importstaticjava.util.Arrays.asList;
importstaticjava.util.Collections.unmodifiableList;
...
publicstaticfinalList<String>names=unmodifiableList(asList(
"Fred","Jim","Sheila"
));
AsperGuideline610,protectedstaticfieldssufferfromthesameproblemsastheirpublicequivalents.
Guideline611/MUTABLE11:Donotexposemutablestatics
Privatestaticsareeasilyexposedthroughpublicinterfaces,ifsometimesonlyinalimitedway(seeGuidelines62and66).Mutablestaticsmay
alsochangebehaviourbetweenunrelatedcode.Toensuresafecode,privatestaticsshouldbetreatedasiftheyarepublic.Addingboilerplateto
exposestaticsassingletonsdoesnotfixtheseissues.
Mutablestaticsmaybeusedascachesofimmutableflyweightvalues.Mutableobjectsshouldneverbecachedinstatics.Eveninstancepoolingof
mutableobjectsshouldbetreatedwithextremecaution.
Somemutablestaticsrequireasecuritypermissiontoupdatestate.Theupdatedvaluewillbevisibleglobally.Thereforemutationshouldbedone
withextremecare.Methodsthatupdateglobalstateorprovideacapabilitytodoso,withasecuritycheck,include:
java.lang.ClassLoader.getSystemClassLoader
java.lang.System.clearProperty
java.lang.System.getProperties
java.lang.System.setErr
java.lang.System.setIn
java.lang.System.setOut
java.lang.System.setProperties
java.lang.System.setProperty
java.lang.System.setSecurityManager
java.net.Authenticator.setDefault
java.net.CookieHandler.getDefault
java.net.CookieHandler.setDefault
java.net.Datagram.setDatagramSocketImplFactory
java.net.HttpURLConnection.setFollowRedirects
java.net.ProxySelector.setDefaul
java.net.ResponseCache.getDefault
java.net.ResponseCache.setDefault
java.net.ServerSocket.setSocketFactory
java.net.Socket.setSocketImplFactory
java.net.URL.setURLStreamHandlerFactory
java.net.URLConnection.setContentHandlerFactory
java.net.URLConnection.setFileNameMap
java.rmi.server.RMISocketFactory.setFailureHandler
java.rmi.server.RMISocketFactory.setSocketFactory
java.rmi,activation.ActivationGroup.createGroup
java.rmi,activation.ActivationGroup.setSystem
java.rmi.server.RMIClassLoader.getDefaultProviderInstance
java.secuirty.Policy.setPolicy
java.sql.DriverManager.setLogStream
java.sql.DriverManager.setLogWriter
java.util.Locale.setDefault
java.util.TimeZone.setDefault
javax.naming.spi.NamingManager.setInitialContextFactoryBuilder
javax.naming.spi.NamingManager.setObjectFactoryBuilder
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory
javax.net.ssl.SSLContext.setDefault
javax.security.auth.login.Configuration.setConfiguration
javax.security.auth.login.Policy.setPolicy
JavaPlugInandJavaWebStartisolatecertainglobalstatewithinan"AppContext".Oftennosecuritypermissionsarenecessarytoaccessthis
state,soitcannotbetrusted(otherthanforSameOriginPolicywithinPlugInandWebStart).Whiletherearesecuritychecks,thestateisstill
intendedtoremainwithinthecontext.ObjectsretrieveddirectlyorindirectlyfromtheAppContextshouldthereforenotbestoredinothervariations
ofglobals,suchasplainstaticsofclassesinasharedclassloader.AnylibrarycodedirectlyorindirectlyusingAppContextonbehalfofan
applicationshouldbeclearlydocumented.UsersofAppContextinclude:
ExtensivelywithinAWT
ExtensivelywithinSwing
ExtensivelywithinJavaBeansLongTermPersistence
java.beans.Beans.setDesignTime
java.beans.Beans.setGuiAvailable
java.beans.Introspector.getBeanInfo
java.beans.PropertyEditorFinder.registerEditor
java.beans.PropertyEditorFinder.setEdiorSearchPath
javax.imageio.ImageIO.createImageInputStream
javax.imageio.ImageIO.createImageOutputStream
javax.imageio.ImageIO.getUseCache
javax.imageio.ImageIO.setCacheDirectory

javax.imageio.ImageIO.setUseCache
javax.print.StreamPrintServiceFactory.lookupStreamPrintServices
javax.print.PrintServiceLookup.lookupDefaultPrintService
javax.print.PrintServiceLookup.lookupMultiDocPrintServices
javax.print.PrintServiceLookup.lookupPrintServices
javax.print.PrintServiceLookup.registerService
javax.print.PrintServiceLookup.registerServiceProvider
Guideline612/MUTABLE12:Donotexposemodifiablecollections
ClassesthatexposeCollectionseitherthroughpublicvariablesorgetmethodshavethepotentialforsideeffects,wherecallingclassescanmodify
contentsoftheCollection.DevelopersshouldconsiderexposingreadonlycopiesofCollectionsrelatingtosecurityauthenticationorinternalstate.
WhileaCollectionobjectreferencecanbemadeimmutablethroughthefinalkeyworddescribedinGuideline69,theactualcontentsofthe
collectionmustbemadeimmutableseparatelythroughtheCollections.unmodifiable...APIs.
publicclassExample{
publicstaticfinalListSIMPLE=
Collections.unmodifiableList(
Arrays.asList("first","second","...")
);
publicstaticfinalMapITEMS;
static{
//Forcomplexitemsrequiringconstruction
Maptemp=newHashMap<>(2);
temp.put("first","Thefirstobject");
temp.put("second","Anotherobject");
ITEMS=Collections.unmodifiableMap(temp);
}

privateListsomethingStateful=newArrayList<>();
publicListgetSomethingStateful(){
returnCollections.unmodifiableList(
somethingStateful);
}
}

7ObjectConstruction
Duringconstructionobjectsareatanawkwardstagewheretheyexistbutarenotreadyforuse.Suchawkwardnesspresentsafewmoredifficulties
inadditiontothoseofordinarymethods.
Guideline71/OBJECT1:Avoidexposingconstructorsofsensitiveclasses
Constructionofclassescanbemorecarefullycontrolledifconstructorsarenotexposed.Definestaticfactorymethodsinsteadofpublic
constructors.Supportextensibilitythroughdelegationratherthaninheritance.Implicitconstructorsthroughserializationandcloneshouldalsobe
avoided.
Guideline72/OBJECT2:Preventtheunauthorizedconstructionofsensitiveclasses
WhereanexistingAPIexposesasecuritysensitiveconstructor,limittheabilitytocreateinstances.Asecuritysensitiveclassenablescallersto
modifyorcircumventSecurityManageraccesscontrols.AnyinstanceofClassLoader,forexample,hasthepowertodefineclasseswith
arbitrarysecuritypermissions.
Torestrictuntrustedcodefrominstantiatingaclass,enforceaSecurityManagercheckatallpointswherethatclasscanbeinstantiated.In
particular,enforceacheckatthebeginningofeachpublicandprotectedconstructor.Inclassesthatdeclarepublicstaticfactorymethodsinplace
ofconstructors,enforcechecksatthebeginningofeachfactorymethod.Alsoenforcechecksatpointswhereaninstanceofaclasscanbecreated
withouttheuseofaconstructor.Specifically,enforceacheckinsidethereadObjectorreadObjectNoDatamethodofaserializableclass,and
insidetheclonemethodofacloneableclass.
Ifthesecuritysensitiveclassisnonfinal,thisguidelinenotonlyblocksthedirectinstantiationofthatclass,itblocksmalicioussubclassingaswell.
Guideline73/OBJECT3:Defendagainstpartiallyinitializedinstancesofnonfinalclasses
Whenaconstructorinanonfinalclassthrowsanexception,attackerscanattempttogainaccesstopartiallyinitializedinstancesofthatclass.
Ensurethatanonfinalclassremainstotallyunusableuntilitsconstructorcompletessuccessfully.
FromJDK6on,constructionofasubclassableclasscanbepreventedbythrowinganexceptionbeforetheObjectconstructorcompletes.Todo
this,performthechecksinanexpressionthatisevaluatedinacalltothis()orsuper().
//nonfinaljava.lang.ClassLoader
publicabstractclassClassLoader{
protectedClassLoader(){
this(securityManagerCheck());
}
privateClassLoader(Voidignored){
//...continueinitialization...
}
privatestaticVoidsecurityManagerCheck(){
SecurityManagersecurity=System.getSecurityManager();
if(security!=null){
security.checkCreateClassLoader();
}
returnnull;
}
}
Forcompatibilitywitholderreleases,apotentialsolutioninvolvestheuseofaninitializedflag.Settheflagasthelastoperationinaconstructor
beforereturningsuccessfully.Allmethodsprovidingagatewaytosensitiveoperationsmustfirstconsulttheflagbeforeproceeding:
publicabstractclassClassLoader{

privatevolatilebooleaninitialized;
protectedClassLoader(){
//permissionneededtocreateClassLoader
securityManagerCheck();
init();
//Lastactionofconstructor.
this.initialized=true;
}
protectedfinalClassdefineClass(...){
checkInitialized();
//regularlogicfollows
...
}
privatevoidcheckInitialized(){
if(!initialized){
thrownewSecurityException(
"NonFinalnotinitialized"
);
}
}
}
Furthermore,anysecuritysensitiveusesofsuchclassesshouldcheckthestateoftheinitializationflag.InthecaseofClassLoaderconstruction,it
shouldcheckthatitsparentclassloaderisinitialized.
Partiallyinitializedinstancesofanonfinalclasscanbeaccessedviaafinalizerattack.Theattackeroverridestheprotectedfinalizemethodina
subclassandattemptstocreateanewinstanceofthatsubclass.Thisattemptfails(intheaboveexample,theSecurityManagercheckin
ClassLoader'sconstructorthrowsasecurityexception),buttheattackersimplyignoresanyexceptionandwaitsforthevirtualmachinetoperform
finalizationonthepartiallyinitializedobject.Whenthatoccursthemaliciousfinalizemethodimplementationisinvoked,givingtheattacker
accesstothis,areferencetotheobjectbeingfinalized.Althoughtheobjectisonlypartiallyinitialized,theattackercanstillinvokemethodsonit,
therebycircumventingtheSecurityManagercheck.Whiletheinitializedflagdoesnotpreventaccesstothepartiallyinitializedobject,itdoes
preventmethodsonthatobjectfromdoinganythingusefulfortheattacker.
Useofaninitializedflag,whilesecure,canbecumbersome.Simplyensuringthatallfieldsinapublicnonfinalclasscontainasafevalue(suchas
null)untilobjectinitializationcompletessuccessfullycanrepresentareasonablealternativeinclassesthatarenotsecuritysensitive.
Amorerobust,butalsomoreverbose,approachistousea"pointertoimplementation"(or"pimpl").Thecoreoftheclassismovedintoanon
publicclasswiththeinterfaceclassforwardingmethodcalls.Anyattemptstousetheclassbeforeitisfullyinitializedwillresultina
NullPointerException.Thisapproachisalsogoodfordealingwithcloneanddeserializationattacks.
publicabstractclassClassLoader{
privatefinalClassLoaderImplimpl;
protectedClassLoader(){
this.impl=newClassLoaderImpl();
}
protectedfinalClassdefineClass(...){
returnimpl.defineClass(...);
}
}
/*pp*/classClassLoaderImpl{
/*pp*/ClassLoaderImpl(){
//permissionneededtocreateClassLoader
securityManagerCheck();
init();
}
/*pp*/ClassdefineClass(...){
//regularlogicfollows
...
}
}
Guideline74/OBJECT4:Preventconstructorsfromcallingmethodsthatcanbeoverridden
Constructorsthatcalloverridablemethodsgiveattackersareferencetothis(theobjectbeingconstructed)beforetheobjecthasbeenfully
initialized.Likewise,clone,readObject,orreadObjectNoDatamethodsthatcalloverridablemethodsmaydothesame.ThereadObject
methodswillusuallycalljava.io.ObjectInputStream.defaultReadObject,whichisanoverridablemethod.
Guideline75/OBJECT5:Defendagainstcloningofnonfinalclasses
Anonfinalclassmaybesubclassedbyaclassthatalsoimplementsjava.lang.Cloneable.Theresultisthatthebaseclasscanbe
unexpectedlycloned,althoughonlyforinstancescreatedbyanadversary.Theclonewillbeashallowcopy.Thetwinswillsharereferenced
objectsbuthavedifferentfieldsandseparateintrinsiclocks.The"pointertoimplementation"approachdetailedinGuideline73providesagood
defense.
8SerializationandDeserialization
JavaSerializationprovidesaninterfacetoclassesthatsidestepsthefieldaccesscontrolmechanismsoftheJavalanguage.Asaresult,caremust
betakenwhenperformingserializationanddeserialization.Furthermore,deserializationofuntrusteddatashouldbeavoidedwheneverpossible,
andshouldbeperformedsafelywhenitcannotbeavoided.
Guideline81/SERIAL1:Avoidserializationforsecuritysensitiveclasses
Securitysensitiveclassesthatarenotserializablewillnothavetheproblemsdetailedinthissection.Makingaclassserializableeffectivelycreates
apublicinterfacetoallfieldsofthatclass.Serializationalsoeffectivelyaddsahiddenpublicconstructortoaclass,whichneedstobeconsidered
whentryingtorestrictobjectconstruction.

Similarly,lambdasshouldbescrutinizedbeforebeingmadeserializable.Functionalinterfacesshouldnotbemadeserializablewithoutdue
considerationforwhatcouldbeexposed.
Guideline82/SERIAL2:Guardsensitivedataduringserialization
OnceanobjecthasbeenserializedtheJavalanguage'saccesscontrolscannolongerbeenforcedandattackerscanaccessprivatefieldsinan
objectbyanalyzingitsserializedbytestream.Therefore,donotserializesensitivedatainaserializableclass.
Approachesforhandlingsensitivefieldsinserializableclassesare:
Declaresensitivefieldstransient
DefinetheserialPersistentFieldsarrayfieldappropriately
ImplementwriteObjectanduseObjectOutputStream.putFieldselectively
ImplementwriteReplacetoreplacetheinstancewithaserialproxy
ImplementtheExternalizableinterface
Guideline83/SERIAL3:Viewdeserializationthesameasobjectconstruction
Deserializationcreatesanewinstanceofaclasswithoutinvokinganyconstructoronthatclass.Therefore,deserializationshouldbedesignedto
behavelikenormalconstruction.
DefaultdeserializationandObjectInputStream.defaultReadObjectcanassignarbitraryobjectstonontransientfieldsanddoesnot
necessarilyreturn.UseObjectInputStream.readFieldsinsteadtoinsertcopyingbeforeassignmenttofields.Or,ifpossible,don'tmake
sensitiveclassesserializable.
publicfinalclassByteStringimplementsjava.io.Serializable{
privatestaticfinallongserialVersionUID=1L;
privatebyte[]data;
publicByteString(byte[]data){
this.data=data.clone();//Makecopybeforeassignment.
}
privatevoidreadObject(
java.io.ObjectInputStreamin
)throwsjava.io.IOException,ClassNotFoundException{
java.io.ObjectInputStreadm.GetFieldfields=
in.readFields();
this.data=((byte[])fields.get("data")).clone();
}
...
}
PerformthesameinputvalidationchecksinareadObjectmethodimplementationasthoseperformedinaconstructor.Likewise,assigndefault
valuesthatareconsistentwiththoseassignedinaconstructortoallfields,includingtransientfields,whicharenotexplicitlysetduring
deserialization.
InadditioncreatecopiesofdeserializedmutableobjectsbeforeassigningthemtointernalfieldsinareadObjectimplementation.Thisdefends
againsthostilecodedeserializingbytestreamsthatarespeciallycraftedtogivetheattackerreferencestomutableobjectsinsidethedeserialized
containerobject.
publicfinalclassNonnegativeimplementsjava.io.Serializable{
privatestaticfinallongserialVersionUID=1L;
privateintvalue;
publicNonnegative(intvalue){
//Makecheckbeforeassignment.
this.data=nonnegative(value);
}
privatestaticintnonnegative(intvalue){
if(value<0){
thrownewIllegalArgumentException(value+
"isnegative");
}
returnvalue;
}
privatevoidreadObject(
java.io.ObjectInputStreamin
)throwsjava.io.IOException,ClassNotFoundException{
java.io.ObjectInputStreadm.GetFieldfields=
in.readFields();
this.value=nonnegative(field.get(value,0));
}
...
}
Attackerscanalsocrafthostilestreamsinanattempttoexploitpartiallyinitialized(deserialized)objects.Ensureaserializableclassremainstotally
unusableuntildeserializationcompletessuccessfully.Forexample,useaninitializedflag.Declaretheflagasaprivatetransientfieldandonly
setitinareadObjectorreadObjectNoDatamethod(andinconstructors)justpriortoreturningsuccessfully.Allpublicandprotectedmethodsin
theclassmustconsulttheinitializedflagbeforeproceedingwiththeirnormallogic.Asdiscussedearlier,useofaninitializedflagcanbe
cumbersome.Simplyensuringthatallfieldscontainasafevalue(suchasnull)untildeserializationsuccessfullycompletescanrepresenta
reasonablealternative.
Guideline84/SERIAL4:DuplicatetheSecurityManagerchecksenforcedinaclassduringserializationanddeserialization
PreventanattackerfromusingserializationordeserializationtobypasstheSecurityManagerchecksenforcedinaclass.Specifically,ifa
serializableclassenforcesaSecurityManagercheckinitsconstructors,thenenforcethatsamecheckinareadObjectorreadObjectNoData
methodimplementation.Otherwiseaninstanceoftheclasscanbecreatedwithoutanycheckviadeserialization.
publicfinalclassSensitiveClassimplementsjava.io.Serializable{
publicSensitiveClass(){
//permissionneededtoinstantiateSensitiveClass
securityManagerCheck();
//regularlogicfollows
}

//implementreadObjecttoenforcechecks
//duringdeserialization
privatevoidreadObject(java.io.ObjectInputStreamin){
//duplicatecheckfromconstructor
securityManagerCheck();
//regularlogicfollows
}
}
Ifaserializableclassenablesinternalstatetobemodifiedbyacaller(viaapublicmethod,forexample)andthemodificationisguardedwitha
SecurityManagercheck,thenenforcethatsamecheckinareadObjectmethodimplementation.Otherwise,anattackercanusedeserialization
tocreateanotherinstanceofanobjectwithmodifiedstatewithoutpassingthecheck.
publicfinalclassSecureNameimplementsjava.io.Serializable{
//privateinternalstate
privateStringname;
privatestaticfinalStringDEFAULT="DEFAULT";
publicSecureName(){
//initializenametodefaultvalue
name=DEFAULT;
}
//allowcallerstomodifyprivateinternalstate
publicvoidsetName(Stringname){
if(name!=null?name.equals(this.name)
:(this.name==null)){
//nochangedonothing
return;
}else{
//permissionneededtomodifyname
securityManagerCheck();
inputValidation(name);
this.name=name;
}
}
//implementreadObjecttoenforcechecks
//duringdeserialization
privatevoidreadObject(java.io.ObjectInputStreamin){
java.io.ObjectInputStream.GetFieldfields=
in.readFields();
Stringname=(String)fields.get("name",DEFAULT);
//ifthedeserializednamedoesnotmatchthedefault
//valuenormallycreatedatconstructiontime,
//duplicatechecks
if(!DEFAULT.equals(name)){
securityManagerCheck();
inputValidation(name);
}
this.name=name;
}
}
IfaserializableclassenablesinternalstatetoberetrievedbyacallerandtheretrievalisguardedwithaSecurityManagerchecktoprevent
disclosureofsensitivedata,thenenforcethatsamecheckinawriteObjectmethodimplementation.Otherwise,anattackercanserializean
objecttobypassthecheckandaccesstheinternalstatesimplybyreadingtheserializedbytestream.
publicfinalclassSecureValueimplementsjava.io.Serializable{
//sensitiveinternalstate
privateStringvalue;
//publicmethodtoallowcallerstoretrieveinternalstate
publicStringgetValue(){
//permissionneededtogetvalue
securityManagerCheck();
returnvalue;
}
//implementwriteObjecttoenforcechecksduringserialization
privatevoidwriteObject(java.io.ObjectOutputStreamout){
//duplicatecheckfromgetValue()
securityManagerCheck();
out.writeObject(value);
}
}
Guideline85/SERIAL5:Understandthesecuritypermissionsgiventoserializationanddeserialization
Permissionsappropriatefordeserializationshouldbecarefullychecked.Additionally,deserializationofuntrusteddatashouldgenerallybe
avoidedwheneverpossible.
SerializationwithfullpermissionsallowspermissionchecksinwriteObjectmethodstobecircumvented.Forinstance,

java.security.GuardedObjectcheckstheguardbeforeserializingthetargetobject.Withfullpermissions,thisguardcanbecircumventedand
thedatafromtheobject(althoughnottheobjectitself)madeavailabletotheattacker.
Deserializationismoresignificant.AnumberofreadObjectimplementationsattempttomakesecuritychecks,whichwillpassiffullpermissions
aregranted.Further,somenonserializablesecuritysensitive,subclassableclasseshavenoargumentconstructors,forinstanceClassLoader.
ConsideramaliciousserializableclassthatsubclassesClassLoader.Duringdeserializationtheserializationmethodcallstheconstructoritself
andthenrunsanyreadObjectinthesubclass.WhentheClassLoaderconstructoriscallednounprivilegedcodeisonthestack,hencesecurity
checkswillpass.Thus,don'tdeserializewithpermissionsunsuitableforthedata.Instead,datashouldbedeserializedwiththeleastnecessary
privileges.
9AccessControl
AlthoughJavaislargelyanobjectcapabilitylanguage,astackbasedaccesscontrolmechanismisusedtosecurelyprovidemoreconventional
APIs.
Guideline91/ACCESS1:Understandhowpermissionsarechecked
Thestandardsecuritycheckensuresthateachframeinthecallstackhastherequiredpermission.Thatis,thecurrentpermissionsinforceisthe
intersectionofthepermissionsofeachframeinthecurrentaccesscontrolcontext.Ifanyframedoesnothaveapermission,nomatterwhereitlies
inthestack,thenthecurrentcontextdoesnothavethatpermission.
Consideranapplicationthatindirectlyusessecureoperationsthroughalibrary.
packagexx.lib;
publicclassLibClass{
privatestaticfinalStringOPTIONS="xx.lib.options";
publicstaticStringgetOptions(){
//checkedbySecurityManager
returnSystem.getProperty(OPTIONS);
}
}
packageyy.app;
classAppClass{
publicstaticvoidmain(String[]args){
System.out.println(
xx.lib.LibClass.getOptions()
);
}
}
Whenthepermissioncheckisperformed,thecallstackwillbeasillustratedbelow.
++
|java.security.AccessController|
|.checkPermission(Permission)|
++
|java.lang.SecurityManager|
|.checkPermission(Permission)|
++
|java.lang.SecurityManager|
|.checkPropertyAccess(String)|
++
|java.lang.System|
|.getProperty(String)|
++
|xx.lib.LibClass|
|.getOptions()|
++
|yy.app.AppClass|
|.main(String[])|
++
Intheaboveexample,iftheAppClassframedoesnothavepermissiontoreadafilebuttheLibClassframedoes,thenasecurityexceptionisstill
thrown.Itdoesnotmatterthattheimmediatecalleroftheprivilegedoperationisfullyprivileged,butthatthereisunprivilegedcodeonthestack
somewhere.
Forlibrarycodetoappeartransparenttoapplicationswithrespecttoprivileges,librariesshouldbegrantedpermissionsatleastasgenerousas
theapplicationcodethatitisusedwith.Forthisreason,almostallthecodeshippedintheJDKandextensionsisfullyprivileged.Itistherefore
importantthattherebeatleastoneframewiththeapplication'spermissionsonthestackwheneveralibraryexecutessecuritycheckedoperations
onbehalfofapplicationcode.
Guideline92/ACCESS2:Bewareofcallbackmethods
Callbackmethodsaregenerallyinvokedfromthesystemwithfullpermissions.Itseemsreasonabletoexpectthatmaliciouscodeneedstobeon
thestackinordertoperformanoperation,butthatisnotthecase.Maliciouscodemaysetupobjectsthatbridgethecallbacktoasecuritychecked
operation.Forinstance,afilechooserdialogboxthatcanmanipulatethefilesystemfromuseractions,mayhaveeventspostedfrommalicious
code.Alternatively,maliciouscodecandisguiseafilechooserassomethingbenignwhileredirectinguserevents.
Callbacksarewidespreadinobjectorientedsystems.Examplesincludethefollowing:
Staticinitializationisoftendonewithfullprivileges
Applicationmainmethod
Applet/Midlet/Servletlifecycleevents
Runnable.run
Thisbridgingbetweencallbackandsecuritysensitiveoperationsisparticularlytrickybecauseitisnoteasytospotthebugortoworkoutwhereit
is.
Whenimplementingcallbacktypes,usethetechniquedescribedinGuideline96totransfercontext.
Guideline93/ACCESS3:Safelyinvokejava.security.AccessController.doPrivileged
AccessController.doPrivilegedenablescodetoexerciseitsownpermissionswhenperformingSecurityManagercheckedoperations.For

thepurposesofsecuritychecks,thecallstackiseffectivelytruncatedbelowthecallerofdoPrivileged.Theimmediatecallerisincludedin
securitychecks.
++
|action|
|.run|
++
|java.security.AccessController|
|.doPrivileged|
++
|SomeClass|
|.someMethod|
++
|OtherClass|
|.otherMethod|
++
||
Intheaboveexample,theprivilegesoftheOtherClassframeareignoredforsecuritychecks.
Toavoidinadvertentlyperformingsuchoperationsonbehalfofunauthorizedcallers,beverycarefulwheninvokingdoPrivilegedusingcaller
providedinputs(taintedinputs):
packagexx.lib;
importjava.security.*;
publicclassLibClass{
//Systempropertyusedbylibrary,
//doesnotcontainsensitiveinformation
privatestaticfinalStringOPTIONS="xx.lib.options";
publicstaticStringgetOptions(){
returnAccessController.doPrivileged(
newPrivilegedAction<String>(){
publicStringrun(){
//thisischeckedbySecurityManager
returnSystem.getProperty(OPTIONS);
}
}
);
}
}
TheimplementationofgetOptionsproperlyretrievesthesystempropertyusingahardcodedvalue.Morespecifically,itdoesnotallowthecaller
toinfluencethenameofthepropertybypassingacallerprovided(tainted)inputtodoPrivileged.
Itisalsoimportanttoensurethatprivilegedoperationsdonotleaksensitiveinformation.WheneverthereturnvalueofdoPrivilegedismade
accessibletountrustedcode,verifythatthereturnedobjectdoesnotexposesensitiveinformation.Intheaboveexample,getOptionsreturnsthe
valueofasystemproperty,butthepropertydoesnotcontainanysensitivedata.
CallerinputsthathavebeenvalidatedcansometimesbesafelyusedwithdoPrivileged.Typicallytheinputsmustberestrictedtoalimitedsetof
acceptable(usuallyhardcoded)values.
Privilegedcodesectionsshouldbemadeassmallaspracticalinordertomakecomprehensionofthesecurityimplicationstractable.
Byconvention,instancesofPrivilegedActionandPrivilegedExceptionActionmaybemadeavailabletountrustedcode,but
doPrivilegedmustnotbeinvokedwithcallerprovidedactions.
ThetwoargumentoverloadsofdoPrivilegedallowchangingofprivilegestothatofapreviousacquiredcontext.Anullcontextisinterpretedas
addingnofurtherrestrictions.Therefore,beforeusingstoredcontexts,makesurethattheyarenotnull(AccessController.getContextnever
returnsnull).
if(acc==null){
thrownewSecurityException("MissingAccessControlContext");
}
AccessController.doPrivileged(newPrivilegedAction<Void>(){
publicVoidrun(){
...
}
},acc);
Guideline94/ACCESS4:KnowhowtorestrictprivilegesthroughdoPrivileged
Aspermissionsarerestrictedtotheintersectionofframes,anartificialAccessControlContextrepresentingno(zero)framesimpliesall
permissions.ThefollowingthreecallstodoPrivilegedareequivalent:
privatestaticfinalAccessControlContextallPermissionsAcc=
newAccessControlContext(
newjava.security.ProtectionDomain[0]
);
voidsomeMethod(PrivilegedAction<Void>action){
AccessController.doPrivileged(action,allPermissionsAcc);
AccessController.doPrivileged(action,null);
AccessController.doPrivileged(action);
}
AllpermissionscanberemovedusinganartificialAccessControlContextcontextcontainingaframeofaProtectionDomainwithno
permissions:
privatestaticfinaljava.security.PermissionCollection
noPermissions=newjava.security.Permissions();
privatestaticfinalAccessControlContextnoPermissionsAcc=
newAccessControlContext(

newProtectionDomain[]{
newProtectionDomain(null,noPermissions)
}
);
voidsomeMethod(PrivilegedAction<Void>action){
AccessController.doPrivileged(newPrivilegedAction<Void>(){
publicVoidrun(){
...contexthasnopermissions...
returnnull;
}
},noPermissionsAcc);
}
++
|ActionImpl|
|.run|
++
||
|noPermissionsAcc|
++
|java.security.AccessController|
|.doPrivileged|
++
|SomeClass|
|.someMethod|
++
|OtherClass|
|.otherMethod|
++
||
Anintermediatesituationispossiblewhereonlyalimitedsetofpermissionsisgranted.Ifthepermissionsarecheckedinthecurrentcontextbefore
beingsuppliedtodoPrivileged,permissionsmaybereducedwithouttheriskofprivilegeelevation.Thisenablestheuseoftheprincipleofleast
privilege:
privatestaticvoiddoWithFile(finalRunnabletask,
StringknownPath){
Permissionperm=newjava.io.FilePermission(knownPath,
"read,write");
//Ensurecontextalreadyhaspermission,
//soprivilegesarenotelevate.
AccessController.checkPermission(perm);
//Executetaskwiththesinglepermissiononly.
PermissionCollectionperms=perm.newPermissionCollection();
perms.add(perm);
AccessController.doPrivileged(newPrivilegedAction<Void>(){
publicVoidrun(){
task.run();
returnnull;
}},
newAccessControlContext(
newProtectionDomain[]{
newProtectionDomain(null,perms)
}
)
);
}
Guideline95/ACCESS5:Becarefulcachingresultsofpotentiallyprivilegedoperations
Acachedresultmustneverbepassedtoacontextthatdoesnothavetherelevantpermissionstogenerateit.Therefore,ensurethattheresultis
generatedinacontextthathasnomorepermissionsthananycontextitisreturnedto.Becausecalculationofprivilegesmaycontainerrors,use
theAccessControllerAPItoenforcetheconstraint.
privatestaticfinalMapcache;
publicstaticThinggetThing(Stringkey){
//Trycache.
CacheEntryentry=cache.get(key);
if(entry!=null){
//Ensurewehaverequiredpermissionsbeforereturning
//cachedresult.
AccessController.checkPermission(entry.getPermission());
returnentry.getValue();
}
//Ensurewedonotelevateprivileges(perGuideline92).
Permissionperm=getPermission(key);
AccessController.checkPermission(perm);
//Createnewvaluewithexactprivileges.
PermissionCollectionperms=perm.newPermissionCollection();
perms.add(perm);
Thingvalue=AccessController.doPrivileged(
newPrivilegedAction<Thing>(){publicThingrun(){
returncreateThing(key);
}},
newAccessControlContext(
newProtectionDomain[]{
newProtectionDomain(null,perms)
}

)
);
cache.put(key,newCacheEntry(value,perm));
returnvalue;
}
Guideline96/ACCESS6:Understandhowtotransfercontext
Itisoftenusefultostoreanaccesscontrolcontextforlateruse.Forexample,onemaydecideitisappropriatetoprovideaccesstocallback
instancesthatperformprivilegedoperations,butinvokecallbackmethodsinthecontextthatthecallbackobjectwasregistered.Thecontextmay
berestoredlateroninthesamethreadorinadifferentthread.Aparticularcontextmayberestoredmultipletimesandevenaftertheoriginal
threadhasexited.
AccessController.getContextreturnsthecurrentcontext.ThetwoargumentformsofAccessController.doPrivilegedcanthenreplace
thecurrentcontextwiththestoredcontextforthedurationofanaction.
packagexx.lib;
publicclassReactor{
publicvoidaddHandler(Handlerhandler){
handlers.add(newHandlerEntry(
handler,AccessController.getContext()
));
}
privatevoidfire(finalHandlerhandler,
AccessControlContextacc){
if(acc==null){
thrownewSecurityException(
"MissingAccessControlContext");
}
AccessController.doPrivileged(
newPrivilegedAction<Void>(){
publicVoidrun(){
handler.handle();
returnnull;
}
},acc);
}
...
}
++
|xx.lib.FileHandler|
|handle()|
++
|xx.lib.Reactor.(anonymous)|
|run()|
++\++
|java.security.AccessController|`||
|.getContext()|+>|acc|
++|++
|xx.lib.Reactor|||java.security.AccessController|
|.addHandler(Handler)|||.doPrivileged(handler,acc)|
++|++
|yy.app.App|||xx.lib.Reactor|
|.main(String[]args)|,|.fire|
++/++
|xx.lib.Reactor|
|.run|
++
||
Guideline97/ACCESS7:Understandhowthreadconstructiontransferscontext
NewlyconstructedthreadsareexecutedwiththeaccesscontrolcontextthatwaspresentwhentheThreadobjectwasconstructed.Inorderto
preventbypassingthiscontext,`voidrun()`ofuntrustedobjectsshouldnotbeexecutedwithinappropriateprivileges.
Guideline98/ACCESS8:SafelyinvokestandardAPIsthatbypassSecurityManagerchecksdependingontheimmediatecaller'sclass
loader
CertainstandardAPIsinthecorelibrariesoftheJavaruntimeenforceSecurityManagerchecksbutallowthosecheckstobebypassed
dependingontheimmediatecaller'sclassloader.Whenthejava.lang.Class.newInstancemethodisinvokedonaClassobject,forexample,
theimmediatecaller'sclassloaderiscomparedtotheClassobject'sclassloader.Ifthecaller'sclassloaderisanancestorof(orthesameas)the
Classobject'sclassloader,thenewInstancemethodbypassesaSecurityManagercheck.(SeeSection4.3.2in[1]forinformationonclass
loaderrelationships).Otherwise,therelevantSecurityManagercheckisenforced.
ThedifferencebetweenthisclassloadercomparisonandaSecurityManagercheckisnoteworthy.ASecurityManagercheckinvestigatesall
callersinthecurrentexecutionchaintoensureeachhasbeengrantedtherequisitesecuritypermission.(IfAccessController.doPrivileged
wasinvokedinthechain,allcallersleadingbacktothecallerofdoPrivilegedarechecked.)Incontrast,theclassloadercomparisononly
investigatestheimmediatecaller'scontext(itsclassloader).ThismeansanycallerwhoinvokesClass.newInstanceandwhohasthecapability
topasstheclassloaderchecktherebybypassingtheSecurityManagereffectivelyperformstheinvocationinsideanimplicit
AccessController.doPrivilegedaction.Becauseofthissubtlety,callersshouldensurethattheydonotinadvertentlyinvoke
Class.newInstanceonbehalfofuntrustedcode.
packageyy.app;
classAppClass{
OtherClassappMethod()throwsException{
returnOtherClass.class.newInstance();
}
}
++
|xx.lib.LibClass|

|.LibClass|
++
|java.lang.Class|
|.newInstance|
++
|yy.app.AppClass|<AppClass.class.getClassLoader
|.appMethod|determinescheck
++
||
Codehasfullaccesstoitsownclassloaderandanyclassloaderthatisadescendent.InthecaseofClass.newInstanceaccesstoaclass
loaderimpliesaccesstoclassesinrestrictedpackages(e.g.,systemclassesprefixedwith"sun.").
Inthediagrambelow,classesloadedbyBhaveaccesstoBanditsdescendentsC,E,andD.Otherclassloaders,showningreystrikeoutfont,are
subjecttosecuritychecks.
++
|bootstraploader|<null
++
^^
++++
|extensionloader||A|
++++
^
++
|systemloader|<Class.getSystemClassLoader()
++
^^
++++
|B||F|
++++
^^^
++++++
|C||E||G|
++++++
^
++
|D|
++
ThefollowingmethodsbehavesimilartoClass.newInstance,andpotentiallybypassSecurityManagerchecksdependingontheimmediate
caller'sclassloader:
java.io.ObjectStreamField.getType
java.io.ObjectStreamClass.forClass
java.lang.Class.newInstance
java.lang.Class.getClassLoader
java.lang.Class.getClasses
java.lang.Class.getField(s)
java.lang.Class.getMethod(s)
java.lang.Class.getConstructor(s)
java.lang.Class.getDeclaredClasses
java.lang.Class.getDeclaredField(s)
java.lang.Class.getDeclaredMethod(s)
java.lang.Class.getDeclaredConstructor(s)
java.lang.Class.getDeclaringClass
java.lang.Class.getEnclosingMethod
java.lang.Class.getEnclosingClass
java.lang.Class.getEnclosingConstructor
java.lang.ClassLoader.getParent
java.lang.ClassLoader.getSystemClassLoader
java.lang.invoke.MethodHandleProxies.asInterfaceInstance
java.lang.reflect.Proxy.getInvocationHandler
java.lang.reflect.Proxy.getProxyClass
java.lang.reflect.Proxy.newProxyInstance
java.lang.Thread.getContextClassLoader
javax.sql.rowset.serial.SerialJavaObject.getFields

Methodssuchasthesethatvarytheirbehavioraccordingtotheimmediatecaller'sclassareconsideredtobecallersensitive,andshouldbe
annotatedincodewiththe@CallerSensitiveannotation[16].
RefrainfrominvokingtheabovemethodsonClass,ClassLoader,orThreadinstancesthatarereceivedfromuntrustedcode.Iftherespective
instanceswereacquiredsafely(orinthecaseofthestaticClassLoader.getSystemClassLoadermethod),donotinvoketheabovemethods
usinginputsprovidedbyuntrustedcode.Also,donotpropagateobjectsthatarereturnedbytheabovemethodsbacktountrustedcode.
Guideline99/ACCESS9:SafelyinvokestandardAPIsthatperformtasksusingtheimmediatecaller'sclassloaderinstance
Thefollowingstaticmethodsperformtasksusingtheimmediatecaller'sclassloader:
java.lang.Class.forName
java.lang.Package.getPackage(s)
java.lang.Runtime.load
java.lang.Runtime.loadLibrary
java.lang.System.load
java.lang.System.loadLibrary
java.sql.DriverManager.deregisterDriver
java.sql.DriverManager.getConnection
java.sql.DriverManager.getDriver(s)
java.util.logging.Logger.getAnonymousLogger
java.util.logging.Logger.getLogger

java.util.ResourceBundle.getBundle
Methodssuchasthesethatvarytheirbehavioraccordingtotheimmediatecaller'sclassareconsideredtobecallersensitive,andshouldbe
annotatedincodewiththe@CallerSensitiveannotation[16].
Forexample,System.loadLibrary("/com/foo/MyLib.so")usestheimmediatecaller'sclassloadertofindandloadthespecifiedlibrary.
(Loadinglibrariesenablesacallertomakenativemethodinvocations.)Donotinvokethismethodonbehalfofuntrustedcode,sinceuntrusted
codemaynothavetheabilitytoloadthesamelibraryusingitsownclassloaderinstance.Donotinvokeanyofthesemethodsusinginputs
providedbyuntrustedcode,anddonotpropagateobjectsthatarereturnedbythesemethodsbacktountrustedcode.
Guideline910/ACCESS10:BeawareofstandardAPIsthatperformJavalanguageaccesschecksagainsttheimmediatecaller
Whenanobjectaccessesfieldsormethodsofanotherobject,theJVMperformsaccesscontrolcheckstoassertthevalidvisiblityofthetarget
methodorfield.Forexample,itpreventsobjectsfrominvokingprivatemethodsinotherobjects.
CodemayalsocallstandardAPIs(primarilyinthejava.lang.reflectpackage)toreflectivelyaccessfieldsormethodsinanotherobject.The
followingreflectionbasedAPIsmirrorthelanguagechecksthatareenforcedbythevirtualmachine:
java.lang.Class.newInstance
java.lang.invoke.MethodHandles.lookup
java.lang.reflect.Constructor.newInstance
java.lang.reflect.Field.get*
java.lang.reflect.Field.set*
java.lang.reflect.Method.invoke
java.util.concurrent.atomic.AtomicIntegerFieldUpdater.newUpdater
java.util.concurrent.atomic.AtomicLongFieldUpdater.newUpdater
java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater
Methodssuchasthesethatvarytheirbehavioraccordingtotheimmediatecaller'sclassareconsideredtobecallersensitive,andshouldbe
annotatedincodewiththe@CallerSensitiveannotation[16].
Languagechecksareperformedsolelyagainsttheimmediatecaller,notagainsteachcallerintheexecutionsequence.Becausetheimmediate
callermayhavecapabilitiesthatothercodelacks(itmaybelongtoaparticularpackageandthereforehaveaccesstoitspackageprivate
members),donotinvoketheaboveAPIsonbehalfofuntrustedcode.Specifically,donotinvoketheabovemethodsonClass,Constructor,
Field,orMethodinstancesthatarereceivedfromuntrustedcode.Iftherespectiveinstanceswereacquiredsafely,donotinvoketheabove
methodsusinginputsthatareprovidedbyuntrustedcode.Also,donotpropagateobjectsthatarereturnedbytheabovemethodsbackto
untrustedcode.
Guideline911/ACCESS11:Beawarejava.lang.reflect.Method.invokeisignoredforcheckingtheimmediatecaller
Consider:
packagexx.lib;
classLibClass{
voidlibMethod(
PrivilegedActionaction
)throwsException{
MethoddoPrivilegedMethod=
AccessController.class.getMethod(
"doPrivileged",PrivilegedAction.class
);
doPrivilegedMethod.invoke(null,action);
}
}
IfMethod.invokewastakenastheimmediatecaller,thentheactionwouldbeperformedwithallpermissions.So,forthemethodsdiscussedin
Guidelines98through910,theMethod.invokeimplementationisignoredwhendeterminingtheimmediatecaller.
++
|action|
|.run|
++
|java.security.AccessController|
|.doPrivileged|
++
|java.lang.reflect.Method|
|.invoke|
++
|xx.lib.LibClass|<Effectivecaller
|.libMethod|
++
||
Therefore,avoidMethod.invoke.
Guideline912/ACCESS12:Avoidusingcallersensitivemethodnamesininterfaceclasses
Whendesigninganinterfaceclass,oneshouldavoidusingmethodswiththesamenameandsignatureofcallersensitivemethods,suchasthose
listedinGuidelines98,99,and910.Inparticular,avoidcallingthesefromdefaultmethodsonaninterfaceclass.
Guideline913/ACCESS13:Avoidreturningtheresultsofprivilegedoperations
Careshouldbetakenwhendesigninglambdaswhicharetobereturnedtountrustedcodeespeciallyonesthatincludesecurityrelated
operations.Withoutproperprecautions,e.g.,inputandoutputvalidation,untrustedcodemaybeabletoleveragetheprivilegesofalambda
inappropriately.
Similarly,careshouldbetakenbeforereturningMethodobjects,MethodHandleobjects,andMethodHandles.Lookupobjectstountrustedcode.
Theseobjectshavechecksforlanguageaccessand/orprivilegesinherentintheircreationandincautiousdistributionmayallowuntrustedcodeto
bypassprivate/protectedaccessrestrictionsaswellasrestrictedpackageaccess.IfonereturnsaMethodorMethodHandleobjectthatan
untrusteduserwouldnotnormallyhaveaccessto,thenacarefulanalysisisrequiredtoensurethattheobjectdoesnotconveyundesirable
capabilities.Similarly,MethodHandles.Lookupobjectshavedifferentcapabilitiesdependingonwhocreatedthem.Itisimportanttounderstand

theaccessgrantedbyanysuchobjectbeforeitisreturnedtountrustedcode.
Conclusion
TheJavaPlatformprovidesarobustbasisforsecuresystemsthroughfeaturessuchasmemorysafety.However,theplatformalonecannot
preventflawsbeingintroduced.Thisdocumentdetailsmanyofthecommonpitfalls.Themosteffectiveapproachtominimizingvulnerabilitiesisto
haveobviouslynoflawsratherthannoobviousflaws.
References
1. LiGong,GaryEllison,andMaryDageforde.
InsideJava2PlatformSecurity.2nded.
Boston,MA:AddisonWesley,2003.
2. JamesGosling,BillJoy,GuySteele,GiladBracha,andAlexBuckley.
TheJavaLanguageSpecification,JavaSE8Edition.
http://docs.oracle.com/javase/specs/
3. TimLindholm,FrankYellin,GiladBracha,andAlexBuckley.
TheJavaVirtualMachineSpecification,JavaSE8Edition.
http://docs.oracle.com/javase/specs/
4. AlephOne.SmashingtheStackforFunandProfit.
Phrack49,November1996.
5. JohnViegaandGaryMcGraw.
BuildingSecureSoftware:HowtoAvoidSecurityProblemstheRightWay.
Boston:AddisonWesley,2002.
6. JoshuaBloch.EffectiveJava.
2nded.AddisonWesleyProfessional,2008.
7. GaryMcGraw.SoftwareSecurity:BuildingSecurityIn.
Boston:AddisonWesley,2006.
8. C.A.R.Hoare.TheEmperor'sOldClothes.
CommunicationsoftheACM,1981
9. JavaSE8SecurityDocumentation
10. Trail:SecurityFeaturesinJavaSE
11. JARFileManifestAttributesforSecurity
12. JavaSE8JavaNativeInterfacerelatedAPIsandDeveloperGuides
13. ShengLiang.
TheJavaNativeInterface:Programmer'sGuideandSpecification.
Boston:AddisonWesley,1999.
14. BlueHatv8:MitigationsUnplugged(Microsoft.com)
15. SecurityResourceCenter
16. JEP176:MechanicalCheckingofCallerSensitiveMethod

AppendixA:DefensiveuseoftheJavaNativeInterface(JNI)
TheJavaNativeInterface(JNI)isastandardprogramminginterfaceforwritingJavanativemethodsandembeddingaJVMintonativeapplications
[12][13].NativeinterfacesallowJavaprogramstointeractwithAPIsthatoriginallydonotprovideJavabindings.JNIsupportsimplementingthese
wrappersinC,C++orassembler.DuringruntimenativemethodsdefinedinadynamicallyloadedlibraryareconnectedtoaJavamethod
declarationwiththenativekeyword.
JNI1:OnlyuseJNIwhennecessary
TheeasiestsecuritymeasureforJNItorememberistoavoidnativecodewheneverpossible.Therefore,thefirsttaskistoidentifyanalternative
thatisimplementedinJavabeforechoosingJNIasanimplementationframework.Thisismainlybecausethedevelopmentchainofwriting,
deploying,andmaintainingnativelibrarieswillburdentheentiredevelopmentchainforthelifetimeofthecomponent.Attackerslikenativecode,
mainlybecauseJNIsecurityfallsbacktothesecurityofC/C++,thereforetheyexpectittobreakfirstwhenattackingacomplexapplication.Whileit
maynotalwaysbepossibletoavoidimplementingnativecode,itshouldstillbekeptasshortaspossibletominimizetheattacksurface.
JNI2:BeawareoftheC/C++threatmodel
AlthoughisitisnotimpossibletofindexploitableholesintheJavalayer,C/C++codingflawsmayprovideattackerswithafasterpathtowards
exploitability.Nativeantipatternsenablememoryexploits(suchasheapandstackbufferoverflows),buttheJavaruntimeenvironmentsafely
managesmemoryandperformsautomaticchecksonaccesswithinarraybounds.Furthermore,Javahasnoexplicitpointerarithmetic.Nativecode
requiresdealingwithheapresourcescarefully,whichmeansthatoperationstoallocateandfreenativememoryrequiresymmetrytoprevent
memoryleaks.
JNI3:ExpectthatJNIcodecanviolateJavavisibilityandisolationrules
TheJavaruntimeenvironmentoftenexecutesuntrustedcode,andprotectionagainstaccesstounauthorizedresourcesisabuiltinfeature.In
C/C++,privateresourcessuchasfiles(containingpasswordsandprivatekeys),systemmemory(privatefields)andsocketsareessentiallyjusta
pointeraway.Existingcodemaycontainvulnerabilitiesthatcouldbeinstrumentedbyanattacker(onolderoperatingsystemssimpleshellcode
injectionwassufficient,whereasadvancedmemoryprotectionswouldrequiretheattackertoapplyreturnorientedprogrammingtechniques).This
meansthatC/C++code,oncesuccessfullyloaded,isnotlimitedbytheJavasecuritypolicyoranyvisibilityrules.
JNI4:SecureyourJNIimplementationfromtheJavaside
Inordertopreventnativecodefrombeingexposedtountrustedandunvalidateddata,JavacodeshouldsanitizedatabeforepassingittoJNI
methods.Thisisalsoimportantforapplicationscenariosthatprocessuntrustedpersistentdata,suchasdeserializationcode.
AsstatedinGuideline53,nativemethodsshouldbeprivateandshouldonlybeaccessedthroughJavabasedwrappermethods.Thisallowsfor
parameterstobevalidatedbyJavacodebeforetheyarepassedtonativecode.Thefollowingexampleillustrateshowtovalidateapairofoffset
andlengthvaluesthatareusedwhenaccessingabytebuffer.TheJavabasedwrappermethodvalidatesthevaluesandchecksforinteger
overflowbeforepassingthevaluestoanativemethod.
publicfinalclassNativeMethodWrapper{
//privatenativemethod
privatenativevoidnativeOperation(byte[]data,
intoffset,intlen);
//wrappermethodperformschecks
publicvoiddoOperation(byte[]data,intoffset,intlen){

//copymutableinput
data=data.clone();

//validateinput
//Noteoffset+lenwouldbesubjecttointegeroverflow.
//Forinstanceifoffset=1andlen=Integer.MAX_VALUE,
//thenoffset+len==Integer.MIN_VALUEwhichislower
//thandata.length.
//Further,
//loopsoftheform
//for(inti=offset;i<offset+len;++i){...}
//wouldnotthrowanexceptionorcausenativecodeto
//crash.
if(offset<0||len<0||offset>data.lengthlen)
{
thrownewIllegalArgumentException();
}

nativeOperation(data,offset,len);
}
}
Whilethislimitsthepropagationofmaliciouslycraftedinputwhichanattackermayusetooverwritenativebuffers,moreaspectsoftheinteraction
betweenJavaandJNIcoderequirespecialcare.Javahidesmemorymanagementdetailsliketheheapobjectallocationviaencapsulation,but
thehandlingofnativeobjectsrequirestheknowledgeoftheirabsolutememoryaddresses.
Topreventmaliciouscodefrommisusingoperationsonnativeobjectstooverwritepartsofmemory,nativeoperationsshouldbedesignedwithout
maintainingstate.Statelessinteractionmaynotalwaysbepossible.Topreventmanipulation,nativememoryaddresseskeptontheJavaside
shouldbekeptinprivatefieldsandtreatedasreadonlyfromtheJavaside.Additionally,referencestonativememoryshouldneverbemade
accessibletountrustedcode.
JNI5:ProperlytestJNIcodeforconcurrentaccess
Especiallywhenmaintainingstate,becarefultestingyourJNIimplementationsothatitbehavesstablyinmultithreadedscenarios.Applyproper
synchronization(preferatomicstolocks,minimizecriticalsections)toavoidraceconditionswhencallingintothenativelayer.Concurrency
unawarecodewillcausememorycorruptionissuesinandaroundtheshareddatasections.
JNI6:Securelibraryloading
TheSystem.loadLibrary("/com/foo/MyLib.so")methodusestheimmediatecaller'sclassloadertofindandloadthespecifiednative
library.Loadinglibrariesenablesacallertoinvokenativemethods.Therefore,donotinvokeloadLibraryinatrustedlibraryonbehalfof
untrustedcode,sinceuntrustedcodemaynothavetheabilitytoloadthesamelibraryusingitsownclassloaderinstance(seeGuidelines98and
99foradditionalinformation).AvoidplacingaloadLibrarycallinaprivilegedblock,asthiswouldallowuntrustedcallerstodirectlytrigger
nativelibraryinitializations.Instead,requireapolicywiththeloadLibrarypermissiongranted.Asmentionedearlier,parametervalidationshould
alsobeperformed,andloadLibraryshouldnotbeinvokedusinginputprovidedbyuntrustedcode.Objectsthatarereturnedbynativemethods
shouldnotbehandedbacktountrustedcode.
JNI7:Performinputvalidationatthelanguageboundary
Toprovideindepthprotectionagainstsecurityissueswithnativememoryaccess,theinputpassedfromtheJavalayerrequiresrevalidationonthe
nativeside.UsingtheruntimeoptionXcheck:jnicanbehelpfulcatchingthoseissues,whichcanbefataltoanapplication,suchaspassingillegal
references,ormixinguparraytypeswithnonarraytypes.Thisoptionwillnotprotectagainstsubtlesemanticconversionerrorsthatcanoccuron
theboundarybetweennativecodeandJava.
SincevaluesinC/C++canbeunsigned,thenativesideshouldcheckforprimitiveparameters(especiallyarrayindices)toblocknegativevalues.
Javacodeisalsowellprotectedagainsttypeconfusion.However,onlyasmallnumberoftypesexistonthenativeside,andalluserobjectswillbe
representedbyinstancesofthejobjecttype.
JNI8:ExpectandhandleexceptionswhencallingfromJNIintoJava
ExceptionsareanimportantconstructoftheJavalanguage,becausetheyhelptodistinguishbetweenthenormalcontrolflowandanyexceptional
conditionsthatcanoccurduringprocessing.ThisallowsJavacodetobepreparedforconditionsthatcausefailure.
NativecodehasnodirectsupportforJavaexceptions,andanyexceptionsthrownbyJavacodewillnotaffectthecontrolflowofnativecode.
Therefore,nativecodeneedstoexplicitlycheckforexceptionsafteroperations,especiallywhencallingintoJavamethodsthatmaythrow
exceptions.Exceptionsmayoccurasynchronously,soitisnecessarytocheckforexceptionsinlongnativeloops.
BeawarethatmanyJNIAPImethods(e.g.GetFieldID)canreturnNULLoranerrorcodewhenanexceptionisthrown.Nativecodefrequently
needstoreturnerrorvaluesandthecallingJavamethodshouldbepreparedtohandlesucherrorconditionsaccordingly.
Unexpectedinputanderrorconditionsmaycausenativecodetobehaveunpredictably.AninputwhitelistlimitstheexposureofJNIcodetoasetof
expectedvalues.
JNI9:Followsecuredevelopmentpracticesforthenativetargetplatform
Modernoperatingsystemsprovideawiderangeofmechanismsthatprotectagainsttheexploitabilityofcommonnativeprogrammingbugs,such
asstackbufferoverflowsandthevarioustypesofheapcorruptions.Stackcookiesprotectagainsttargetedoverwriteofreturnaddressesonthe
stack,whichanattackercouldotherwiseusetodivertcontrolflow.AddressSpaceLayoutRandomizationpreventsattackersfromplacingformerly
wellknownreturnadressesonthestack,whichwhenreturningfromasubroutinecallsystemscodesuchasexecveontheattackersbehalf.With
theaboveprotections,attackersmaystillchoosetoplacenativecodesnippets(shellcode)withinthedataheap,anattackvectorthatisprevented
whentheoperatingsystemallowstoflagamemorypageasNonexecutable(NX).
Whenbuildingnativelibraries,someoftheabovetechniquesmaynotbeenabledbydefaultandmayrequireanexplicitoptinbythelibrary
bootstrapcode.Ineithercaseitiscrucialtoknowandunderstandthesecuredevelopmentpracticeforagivenoperatingsystem,andadaptthe
compileandbuildscriptsaccordingly[14].
JavaSDKsandTools
JavaSE
JavaEEandGlassfish
JavaME

JavaCard
NetBeansIDE
JavaMissionControl
JavaResources
JavaAPIs
TechnicalArticles
DemosandVideos
Forums
JavaMagazine
Java.net
DeveloperTraining
Tutorials
Java.com

Vous aimerez peut-être aussi